diff --git a/leed/Configuration.class.php b/leed/Configuration.class.php
deleted file mode 100644
index 8f634a78d840ab4881421771d6616637b70565ca..0000000000000000000000000000000000000000
--- a/leed/Configuration.class.php
+++ /dev/null
@@ -1,159 +0,0 @@
-<?php
-
-
-/*
- @nom: Configuration
- @auteur: Idleman (http://blog.idleman.fr)
- @description: Classe de gestion des préférences, fonctionne sur un simple système clé=>valeur avec un cache session pour eviter les requête inutiles
- */
-
-class Configuration extends MysqlEntity{
-
-    protected $id,$key,$value,$confTab;
-    protected $TABLE_NAME = 'configuration';
-    protected $object_fields =
-    array(
-        'id'=>'key',
-        'key'=>'string',
-        'value'=>'longstring'
-    );
-
-    protected $object_fields_uniques =
-    array(
-        'key'
-    );
-
-    protected $options = array(
-        'articleDisplayAnonymous' => '0',
-        'articleDisplayAuthor' => '1',
-        'articleDisplayDate' => '1',
-        'articleDisplayFolderSort' => '1',
-        'articleDisplayHomeSort' => '1',
-        'articleDisplayLink' => '1',
-        'articleDisplayMode' => 'summary',
-        'articlePerPages' => '5',
-        'displayOnlyUnreadFeedFolder' => 'false',
-        'feedMaxEvents' => '50',
-        'language' => 'en',
-        'optionFeedIsVerbose' => 1,
-        'paginationScale' => 5,
-        'syncGradCount' => '10',
-        'synchronisationCode' => '',
-        'synchronisationEnableCache' => '0',
-        'synchronisationForceFeed' => '0',
-        'synchronisationType' => 'auto',
-        'theme' => 'marigolds',
-        'root' => '',
-        'cryptographicSalt' => '',
-        'otpEnabled' => 0
-    );
-
-    function __construct(){
-        parent::__construct();
-    }
-
-    public function getAll(){
-
-        if(!isset($_SESSION['configuration'])){
-
-        $configurationManager = new Configuration();
-        $configs = $configurationManager->populate();
-        $confTab = array();
-
-        foreach($configs as $config){
-            $this->confTab[$config->getKey()] = $config->getValue();
-        }
-
-        $_SESSION['configuration'] = serialize($this->confTab);
-
-        }else{
-            $this->confTab = unserialize($_SESSION['configuration']);
-        }
-    }
-
-    public function get($key){
-
-        return (isset($this->confTab[$key])?$this->confTab[$key]:'');
-    }
-
-    public function put($key,$value){
-        $configurationManager = new Configuration();
-        if (isset($this->confTab[$key])){
-            $configurationManager->change(array('value'=>$value),array('key'=>$key));
-        } else {
-            $configurationManager->add($key,$value);
-        }
-        $this->confTab[$key] = $value;
-        unset($_SESSION['configuration']);
-    }
-
-    protected function createSynchronisationCode() {
-        return substr(sha1(rand(0,30).time().rand(0,30)),0,10);
-    }
-
-    public function add($key,$value){
-        $config = new Configuration();
-        $config->setKey($key);
-        $config->setValue($value);
-        $config->save();
-        $this->confTab[$key] = $value;
-        unset($_SESSION['configuration']);
-    }
-
-    public function setDefaults() {
-        foreach($this->options as $option => $defaultValue) {
-            switch($option) {
-                case 'language':
-                    $value = isset($_POST['install_changeLngLeed']) ? $_POST['install_changeLngLeed'] : $defaultValue;
-                    break;
-                case 'theme':
-                    $value = isset($_POST['template']) ? $_POST['template'] : $defaultValue;
-                    break;
-                case 'synchronisationCode':
-                    $value = $this->createSynchronisationCode();
-                    break;
-                case 'root':
-                    $root = $_POST['root'];
-                    $value = (substr($root, strlen($root)-1)=='/'?$root:$root.'/');
-                    break;
-                case 'cryptographicSalt':
-                    $value = $this->generateSalt();
-                    break;
-                default:
-                    $value = $defaultValue;
-                    break;
-            }
-            $this->add($option, $value);
-        }
-    }
-
-    protected function generateSalt() {
-        return ''.mt_rand().mt_rand();
-    }
-
-    function getId(){
-        return $this->id;
-    }
-
-    function getKey(){
-        return $this->key;
-    }
-
-    function setKey($key){
-        $this->key = $key;
-    }
-
-    function getValue(){
-        return $this->value;
-    }
-
-    function setValue($value){
-        $this->value = $value;
-    }
-
-
-
-
-}
-
-?>
diff --git a/leed/Event.class.php b/leed/Event.class.php
deleted file mode 100644
index fb0a0c877d19041563221471cc65dbdad9dc0f89..0000000000000000000000000000000000000000
--- a/leed/Event.class.php
+++ /dev/null
@@ -1,213 +0,0 @@
-<?php
-
-/*
- @nom: Event
- @auteur: Idleman (http://blog.idleman.fr)
- @description: Classe de gestion des évenements/news liés a chaques flux RSS/ATOM
- */
-
-class Event extends MysqlEntity{
-
-    protected $id,$title,$guid,$content,$description,$pudate,$link,$feed,$category,$creator,$unread,$favorite;
-    protected $TABLE_NAME = 'event';
-    protected $object_fields =
-    array(
-        'id'=>'key',
-        'guid'=>'longstring',
-        'title'=>'string',
-        'creator'=>'string',
-        'content'=>'extralongstring',
-        'description'=>'longstring',
-        'link'=>'longstring',
-        'unread'=>'integer',
-        'feed'=>'integer',
-        'unread'=>'integer',
-        'favorite'=>'integer',
-        'pubdate'=>'integer',
-        'syncId'=>'integer',
-    );
-
-    protected $object_fields_index =
-    array(
-        'feed'=>'index',
-        'unread'=>'index',
-        'favorite'=>'index'
-    );
-
-    function __construct($guid=null,$title=null,$description=null,$content=null,$pubdate=null,$link=null,$category=null,$creator=null){
-
-        $this->guid = $guid;
-        $this->title = $title;
-        $this->creator = $creator;
-        $this->content = $content;
-        $this->description = $description;
-        $this->pubdate = $pubdate;
-        $this->link = $link;
-        $this->category = $category;
-        parent::__construct();
-    }
-
-
-    function getEventCountPerFolder(){
-        $events = array();
-        $results = $this->customQuery('SELECT COUNT(`'.MYSQL_PREFIX.$this->TABLE_NAME.'`.`id`),`'.MYSQL_PREFIX.'feed`.`folder` FROM `'.MYSQL_PREFIX.$this->TABLE_NAME.'` LEFT JOIN `'.MYSQL_PREFIX.'feed` ON (`'.MYSQL_PREFIX.'event`.`feed` = `'.MYSQL_PREFIX.'feed`.`id`) WHERE `'.MYSQL_PREFIX.$this->TABLE_NAME.'`.`unread`=1 GROUP BY `'.MYSQL_PREFIX.'feed`.`folder`');
-        while($item = $results->fetch_array()){
-            $events[$item[1]] = intval($item[0]);
-        }
-
-        return $events;
-    }
-
-    function getEventCountNotVerboseFeed(){
-        $results = $this->customQuery('SELECT COUNT(1) FROM `'.MYSQL_PREFIX.$this->TABLE_NAME.'` LEFT JOIN `'.MYSQL_PREFIX.'feed` ON (`'.MYSQL_PREFIX.'event`.`feed` = `'.MYSQL_PREFIX.'feed`.`id`) WHERE `'.MYSQL_PREFIX.$this->TABLE_NAME.'`.`unread`=1 AND `'.MYSQL_PREFIX.'feed`.`isverbose`=0');
-        while($item = $results->fetch_array()){
-            $nbitem =  $item[0];
-        }
-
-        return $nbitem;
-    }
-
-    function getEventsNotVerboseFeed($order,$start=0,$limit=10000,$columns='*'){
-        $eventManager = new Event();
-        $objects = array();
-        $results = $this->customQuery('SELECT '.$columns.' FROM `'.MYSQL_PREFIX.'event` LEFT JOIN `'.MYSQL_PREFIX.'feed` ON (`'.MYSQL_PREFIX.'event`.`feed` = `'.MYSQL_PREFIX.'feed`.`id`) WHERE `'.MYSQL_PREFIX.'event`.`unread`=1 AND `'.MYSQL_PREFIX.'feed`.`isverbose` = 0 ORDER BY '.$order.' LIMIT '.$start.','.$limit);
-        if($results!=false){
-            while($item = $results->fetch_array()){
-                $object = new Event();
-                foreach($object->getObject_fields() as $field=>$type){
-                    $setter = 'set'.ucFirst($field);
-                    if(isset($item[$field])) $object->$setter($item[$field]);
-                }
-                $objects[] = $object;
-                unset($object);
-            }
-        }
-        return $objects;
-    }
-
-    function setId($id){
-        $this->id = $id;
-    }
-
-    function getCreator(){
-        return $this->creator;
-    }
-
-    function setCreator($creator){
-        $this->creator = $creator;
-    }
-
-    function getCategory(){
-        return $this->category;
-    }
-
-    function setCategory($category){
-        $this->category = $category;
-    }
-
-    function getDescription(){
-        return $this->description;
-    }
-
-    function setDescription($description,$encoding = true){
-        $this->description = $description;
-    }
-
-    function getPubdate($format=false){
-        if($this->pubdate!=0){
-        return ($format!=false?date($format,$this->pubdate):$this->pubdate);
-        }else{
-            return '';
-        }
-    }
-
-    function getPubdateWithInstant($instant){
-        if (empty($this->pubdate)) return '';
-        $alpha = $instant - $this->pubdate;
-        if ($alpha < 86400 ){
-            $hour = floor($alpha/3600);
-            $alpha = ($hour!=0?$alpha-($hour*3600):$alpha);
-            $minuts = floor($alpha/60);
-            if ($hour!=0) {
-                return _t('PUBDATE_WITHINSTANT_LOWERH24',array($hour,$minuts));
-            } else {
-                return _t('PUBDATE_WITHINSTANT_LOWERH1',array($minuts));
-            }
-        }else{
-            $date=$this->getPubdate(_t('FORMAT_DATE_HOURS'));
-            return _t('PUBDATE_WITHINSTANT',array($date));
-        }
-    }
-
-    function setPubdate($pubdate){
-        $this->pubdate = (is_numeric($pubdate)?$pubdate:strtotime($pubdate));
-    }
-
-    function getLink(){
-        return $this->link;
-    }
-
-    function setLink($link){
-        $this->link = $link;
-    }
-
-    function getId(){
-        return $this->id;
-    }
-
-    function getTitle(){
-        return $this->title;
-    }
-
-    function setTitle($title){
-        $this->title = $title;
-    }
-
-    function getContent(){
-        return $this->content;
-    }
-
-    function setContent($content,$encoding=true){
-        $this->content = $content;
-    }
-
-
-    function getGuid(){
-        return $this->guid;
-    }
-
-    function setGuid($guid){
-        $this->guid = $guid;
-    }
-
-    function getSyncId(){
-        return $this->syncId;
-    }
-
-    function setSyncId($syncId){
-        $this->syncId = $syncId;
-    }
-
-    function getUnread(){
-        return $this->unread;
-    }
-
-    function setUnread($unread){
-        $this->unread = $unread;
-    }
-    function setFeed($feed){
-        $this->feed = $feed;
-    }
-    function getFeed(){
-        return $this->feed;
-    }
-    function setFavorite($favorite){
-        $this->favorite = $favorite;
-    }
-    function getFavorite(){
-        return $this->favorite;
-    }
-
-}
-
-?>
diff --git a/leed/Feed.class.php b/leed/Feed.class.php
deleted file mode 100644
index 8f02f470bd27fe5e6f9523bc8a1efb664acfc400..0000000000000000000000000000000000000000
--- a/leed/Feed.class.php
+++ /dev/null
@@ -1,406 +0,0 @@
-<?php
-
-/*
- @nom: Feed
- @auteur: Idleman (http://blog.idleman.fr)
- @description: Classe de gestion des flux RSS/ATOM
- */
-
-class Feed extends MysqlEntity{
-
-    protected $id,$name,$url,$events=array(),$description,$website,$folder,$lastupdate,$isverbose,$lastSyncInError;
-    protected $TABLE_NAME = 'feed';
-    protected $object_fields =
-    array(
-        'id'=>'key',
-        'name'=>'string',
-        'description'=>'longstring',
-        'website'=>'longstring',
-        'url'=>'longstring',
-        'lastupdate'=>'string',
-        'folder'=>'integer',
-        'isverbose'=>'boolean',
-        'lastSyncInError'=>'boolean',
-    );
-
-    protected $object_fields_index =
-    array(
-        'folder'=>'index'
-    );
-
-    protected $error = '';
-
-    function __construct($name=null,$url=null){
-        $this->name = $name;
-        $this->url = $url;
-        parent::__construct();
-    }
-
-    function getError() { return $this->error; }
-    function getLastSyncInError() { return $this->lastSyncInError; }
-
-    /*@TODO: fournir un extrait quand il 'y a pas de description. De même pour les médias.
-    @TODO: SimplePie remplace "é" par "&eacute;", il ne devrait pas le faire.
-    J'ai testé set_stupidly_fast(true) sans succès.
-    Il encadre les descriptions avec <div>, absents dans le source du flux.
-    @TODO: la vérification de doublon est sous la responsabilité de l'appelant.
-    Il serait peut-être utile de faire une méthode add() qui vérifie, plante si
-    nécessaire, et appelle parse(). Impossible de vérifier dans parse() même
-    car elle est appelée aussi pour autre chose que l'ajout.
-    */
-    function parse($syncId,&$nbEvents =0, $enableCache=true, $forceFeed=false){
-        $nbEvents = 0;
-        $isSyncIdOk = is_int($syncId) && $syncId > 0;
-        assert($isSyncIdOk);
-        if (empty($this->id) || 0 == $this->id) {
-            /* Le flux ne dispose pas pas d'id !. Ça arrive si on appelle
-            parse() sans avoir appelé save() pour un nouveau flux.
-            @TODO: un create() pour un nouveau flux ? */
-            $msg = 'Empty or null id for a feed! '
-                  .'See '.__FILE__.' on line '.__LINE__;
-            error_log($msg, E_USER_ERROR);
-            die($msg); // Arrêt, sinon création événements sans flux associé.
-        }
-        $feed = new SimplePie();
-        $feed->enable_cache($enableCache);
-        $feed->force_feed($forceFeed);
-        $feed->set_feed_url($this->url);
-        $feed->set_useragent('Mozilla/4.0 Leed (LightFeed Aggregator) ' . LEED_VERSION_NAME);
-        $this->lastSyncInError = 0;
-        $this->lastupdate = $_SERVER['REQUEST_TIME'];
-        if (!$feed->init()) {
-            $this->error = $feed->error;
-            $this->lastSyncInError = 1;
-            $this->save();
-            return false;
-        }
-
-        $feed->handle_content_type(); // UTF-8 par défaut pour SimplePie
-
-        if($this->name == '') $this->name = $feed->get_title();
-        if($this->name == '') $this->name = $this->url;
-        if($this->website == '') $this->website = $feed->get_link();
-        if($this->description == '') $this->description = $feed->get_description();
-
-        $items = $feed->get_items();
-        $eventManager = new Event();
-
-        $events = array();
-        $iEvents = 0;
-        foreach($items as $item){
-            // Ne retient que les 100 premiers éléments de flux.
-            if ($iEvents++>=100) break;
-
-            // Si le guid existe déjà, on évite de le reparcourir.
-            $alreadyParsed = $eventManager->load(array('guid'=>$item->get_id(), 'feed'=>$this->id));
-            if (isset($alreadyParsed)&&($alreadyParsed!=false)) {
-                $events[]=$alreadyParsed->getId();
-                continue;
-            }
-
-            // Initialisation des informations de l'événement (élt. de flux)
-            $event = new Event();
-            $event->setSyncId($syncId);
-            $event->setGuid($item->get_id());
-            $event->setTitle(html_entity_decode(htmlspecialchars_decode($item->get_title())));
-            $event->setPubdate(
-                ''==$item->get_date()
-                    ? $this->lastupdate
-                    : $item->get_date()
-            );
-            $event->setCreator(
-                ''==$item->get_author()
-                    ? ''
-                    : $item->get_author()->name
-            );
-            $event->setLink($item->get_permalink());
-
-            $event->setFeed($this->id);
-            $event->setUnread(1); // inexistant, donc non-lu
-            $enclosure = $this->getEnclosureHtml($item->get_enclosure());
-            $event->setContent($item->get_content().$enclosure);
-            $event->setDescription($item->get_description().$enclosure);
-
-            if(trim($event->getDescription())=='')
-                $event->setDescription(
-                    substr($event->getContent(),0,300)
-                    .'…<br><a href="'.$event->getLink()
-                    .'">Lire la suite de l\'article</a>'
-                );
-            if(trim($event->getContent())=='')
-                $event->setContent($event->getDescription());
-
-            $event->setCategory($item->get_category());
-            $event->save();
-            $nbEvents++;
-        }
-
-        $listid = "";
-        foreach($events as $item){
-            $listid.=','.$item;
-        }
-        $query='UPDATE `'.MYSQL_PREFIX.'event` SET syncId='.$syncId.' WHERE id in (0'.$listid.');';
-        $myQuery = $this->customQuery($query);
-
-        $this->save();
-        return true;
-    }
-
-    protected function getEnclosureHtml($enclosure) {
-        global $i18n;
-	$html = '';
-        if($enclosure!=null && $enclosure->link!=''){
-            $enclosureName = substr(
-                $enclosure->link,
-                strrpos($enclosure->link, '/')+1,
-                strlen($enclosure->link)
-            );
-            $enclosureArgs = strpos($enclosureName, '?');
-            if($enclosureArgs!==false)
-                $enclosureName = substr($enclosureName,0,$enclosureArgs);
-            $enclosureFormat = isset($enclosure->handler)
-                ? $enclosure->handler
-                : substr($enclosureName, strrpos($enclosureName,'.')+1);
-
-            $html ='<div class="enclosure"><h1>Fichier média :</h1>';
-            $enclosureType = $enclosure->get_type();
-            if (strpos($enclosureType, 'image/') === 0) {
-                $html .= '<img src="' . $enclosure->link . '" />';
-            } elseif (strpos($enclosureType, 'audio/') === 0 || strpos($enclosureType, 'application/ogg') === 0) {
-                $html .= '<audio src="' . $enclosure->link . '" preload="none" controls>'._t('BROWSER_AUDIO_ELEMENT_NOT_SUPPORTED').'</audio>';
-            } elseif (strpos($enclosureType, 'video/') === 0) {
-                $html .= '<video src="' . $enclosure->link . '" preload="none" controls>'._t('BROWSER_VIDEO_ELEMENT_NOT_SUPPORTED').'</video>';
-            } else {
-                $html .= '<a href="'.$enclosure->link.'"> '.$enclosureName.'</a>';
-            }
-            $html .= ' <span>(Format '.strtoupper($enclosureFormat).', '.Functions::convertFileSize($enclosure->length).')</span></div>';
-        }
-        return $html;
-    }
-
-
-    function removeOldEvents($maxEvent, $currentSyncId){
-        if ($maxEvent<=0) return;
-        $eventManager = new Event();
-        $nbLines = $eventManager->rowCount(array(
-            'feed'=>$this->id,
-             'unread'=>0,
-            'favorite'=>0,
-        ));
-        $limit = $nbLines - $maxEvent;
-        if ($limit<=0) return;
-        $tableEvent = '`'.MYSQL_PREFIX."event`";
-        $query = "
-            DELETE FROM {$tableEvent} WHERE feed={$this->id} AND favorite!=1 AND unread!=1 AND syncId!={$currentSyncId} ORDER BY pubdate ASC LIMIT {$limit}
-        ";
-        ///@TODO: escape the variables inside mysql
-         $this->customQuery($query);
-    }
-
-    function setId($id){
-        $this->id = $id;
-    }
-
-    function getDescription(){
-        return $this->description;
-    }
-
-    function setDescription($description){
-        $this->description = $description;
-    }
-    function getWebSite(){
-        return $this->website;
-    }
-
-    function setWebSite($website){
-        $this->website = $website;
-    }
-
-    function getId(){
-        return $this->id;
-    }
-
-    function getUrl(){
-        return $this->url;
-    }
-
-    function setUrl($url){
-        $this->url = $url;
-    }
-
-    function getName(){
-        return (trim($this->name)!='' ? $this->name:$this->url);
-    }
-
-    function setName($name){
-        $this->name = $name;
-    }
-
-
-    function getEvents($order,$start=0,$limit=10000,$columns='*',$filter=[]){
-        $filter['feed'] = $this->getId();
-        $eventManager = new Event();
-        $events = $eventManager->loadAllOnlyColumn($columns,$filter,$order,$start.','.$limit);
-        return $events;
-    }
-
-    function countUnreadEvents(){
-        $unreads = array();
-        $results = Feed::customQuery("SELECT COUNT(`".MYSQL_PREFIX."event`.`id`), `".MYSQL_PREFIX."event`.`feed` FROM `".MYSQL_PREFIX."event` WHERE `".MYSQL_PREFIX."event`.`unread` = 1 GROUP BY `".MYSQL_PREFIX."event`.`feed`") ;
-        if($results!=false){
-            $total = 0;
-            while($item = $results->fetch_array()){
-                $unreads[$item[1]] = $item[0];
-                $total += $item[0];
-            }
-            $unreads['total'] = $total;
-        }
-        return $unreads;
-    }
-
-    function getFeedsPerFolder(){
-        $feedsFolderMap = array();
-        $feedsIdMap = array();
-
-        $results = Feed::customQuery("SELECT `".MYSQL_PREFIX."feed`.`name` AS name, `".MYSQL_PREFIX."feed`.`id`   AS id, `".MYSQL_PREFIX."feed`.`url`  AS url, `".MYSQL_PREFIX."folder`.`id` AS folder FROM `".MYSQL_PREFIX."feed` LEFT JOIN `".MYSQL_PREFIX."folder` ON ( `".MYSQL_PREFIX."feed`.`folder` = `".MYSQL_PREFIX."folder`.`id` ) ORDER BY `".MYSQL_PREFIX."feed`.`name` ;");
-        if($results!=false){
-            while($item = $results->fetch_array()){
-                $name = $item['name'];
-                $feedsIdMap[$item['id']]['name'] = $name;
-
-
-                $feedsFolderMap[$item['folder']][$item['id']]['id'] = $item['id'];
-                $feedsFolderMap[$item['folder']][$item['id']]['name'] = $name;
-                $feedsFolderMap[$item['folder']][$item['id']]['url'] = $item['url'];
-
-            }
-        }
-        $feeds['folderMap'] = $feedsFolderMap;
-        $feeds['idMap'] = $feedsIdMap;
-        return $feeds;
-    }
-
-    function getFolder(){
-        return $this->folder;
-    }
-
-    function setFolder($folder){
-        $this->folder = $folder;
-    }
-
-    function getLastupdate(){
-        return $this->lastupdate;
-    }
-
-    function setLastupdate($lastupdate){
-        $this->lastupdate = $lastupdate;
-    }
-
-    function getIsverbose(){
-        return $this->isverbose;
-    }
-
-    function setIsverbose($isverbose){
-        $this->isverbose = $isverbose;
-    }
-
-    /** @returns vrai si l'url n'est pas déjà connue .*/
-    function notRegistered() {
-        return $this->rowCount(array('url' => $this->url)) == 0;
-    }
-
-    public function synchronize($feeds, $syncTypeStr, $commandLine, $configurationManager, $start) {
-        $currentDate = date('d/m/Y H:i:s');
-        if (!$commandLine) {
-            echo "<p>{$syncTypeStr} {$currentDate}</p>\n";
-            echo "<dl>\n";
-        } else {
-            echo "{$syncTypeStr}\t{$currentDate}\n";
-        }
-        $maxEvents = $configurationManager->get('feedMaxEvents');
-        $nbErrors = 0;
-        $nbOk = 0;
-        $nbTotal = 0;
-        $localTotal = 0; // somme de tous les temps locaux, pour chaque flux
-        $nbTotalEvents = 0;
-        $syncId = time();
-        $enableCache = ($configurationManager->get('synchronisationEnableCache')=='')?0:$configurationManager->get('synchronisationEnableCache');
-        $forceFeed = ($configurationManager->get('synchronisationForceFeed')=='')?0:$configurationManager->get('synchronisationForceFeed');
-
-        foreach ($feeds as $feed) {
-            $nbEvents = 0;
-            $nbTotal++;
-            $startLocal = microtime(true);
-            $parseOk = $feed->parse($syncId,$nbEvents, $enableCache, $forceFeed);
-            $parseTime = microtime(true)-$startLocal;
-            $localTotal += $parseTime;
-            $parseTimeStr = number_format($parseTime, 3);
-            if ($parseOk) { // It's ok
-                $errors = array();
-                $nbTotalEvents += $nbEvents;
-                $nbOk++;
-            } else {
-                // tableau au cas où il arrive plusieurs erreurs
-                $errors = array($feed->getError());
-
-                $nbErrors++;
-            }
-            $feedName = Functions::truncate($feed->getName(),30);
-            $feedUrl = $feed->getUrl();
-            $feedUrlTxt = Functions::truncate($feedUrl, 30);
-            if ($commandLine) {
-                echo date('d/m/Y H:i:s')."\t".$parseTimeStr."\t";
-                echo "{$feedName}\t{$feedUrlTxt}\n";
-            } else {
-                if (!$parseOk)
-                    echo '<div class="errorSync">';
-                else
-                    echo '<div>';
-                echo "<dt><i>{$parseTimeStr}s</i> | <a target='_blank' rel='noopener noreferrer' href='{$feedUrl}'>{$feedName}</a></dt>\n";
-
-            }
-            foreach($errors as $error) {
-                if ($commandLine)
-                    echo "$error\n";
-                else
-                    echo "<dd>$error</dd>\n";
-            }
-            if (!$parseOk && !$commandLine) echo '</div>';
-//             if ($commandLine) echo "\n";
-            $feed->removeOldEvents($maxEvents, $syncId);
-        }
-        $isTotalOk = $nbTotal === $nbOk + $nbErrors;
-        assert($isTotalOk);
-        $totalTime = microtime(true)-$start;
-        $totalTimeStr = number_format($totalTime, 3);
-        $currentDate = date('d/m/Y H:i:s');
-        if ($commandLine) {
-            echo "\t{$nbErrors}\t"._t('ERRORS')."\n";
-            echo "\t{$nbOk}\t"._t('GOOD')."\n";
-            echo "\t{$nbTotal}\t"._t('AT_TOTAL')."\n";
-            echo "\t$currentDate\n";
-            echo "\t$nbTotalEvents\n";
-            echo "\t{$totalTimeStr}\t"._t('SECONDS')."\n";
-        } else {
-            echo "</dl>\n";
-            echo "<div id='syncSummary'\n";
-            echo "<p>"._t('SYNCHRONISATION_COMPLETE')."</p>\n";
-            echo "<ul>\n";
-            echo "<li>{$nbErrors}\t"._t('ERRORS')."\n";
-            echo "<li>{$nbOk}\t"._t('GOOD')."\n";
-            echo "<li>{$nbTotal}\t"._t('AT_TOTAL')."\n";
-            echo "<li>{$totalTimeStr}\t"._t('SECONDS')."\n";
-            echo "<li>{$nbTotalEvents}\t"._t('NEW_ARTICLES')."\n";
-            echo "</ul>\n";
-            echo "</div>\n";
-        }
-
-        if (!$commandLine) {
-            echo '</div></body></html>';
-        }
-
-    }
-
-}
-
-?>
diff --git a/leed/Folder.class.php b/leed/Folder.class.php
deleted file mode 100644
index b867a8b0a203c0732c3cabef6bc0ee9773f87835..0000000000000000000000000000000000000000
--- a/leed/Folder.class.php
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-
-/*
- @nom: Folder
- @auteur: Idleman (http://blog.idleman.fr)
- @description: Classe de gestion des dossiers/catégories contenant les flux
- */
-
-class Folder extends MysqlEntity{
-
-    protected $id,$name,$parent,$isopen;
-    protected $TABLE_NAME = 'folder';
-    protected $object_fields =
-    array(
-        'id'=>'key',
-        'name'=>'string',
-        'parent'=>'integer',
-        'isopen'=>'integer'
-    );
-
-    function unreadCount(){
-        $results = $this->customQuery('SELECT COUNT(`'.MYSQL_PREFIX.'event`.`id`) FROM `'.MYSQL_PREFIX.'event` LEFT JOIN `'.MYSQL_PREFIX.'feed` ON (`'.MYSQL_PREFIX.'event`.`feed` = `'.MYSQL_PREFIX.'feed`.`id`) WHERE `'.MYSQL_PREFIX.'event`.`unread`=1 AND `'.MYSQL_PREFIX.'feed`.`folder` = '.$this->getId());
-        $number = $results->fetch_array();
-        return $number[0];
-    }
-
-
-    function getEvents($order,$start=0,$limit=10000,$columns='*',$filter=[]){
-        if(!isset($filter['unread'])) {
-            $filter['unread'] = 1;
-        }
-        $filter['folder'] = $this->getId();
-        $whereClause = $this->getWhereClause($filter,'=');
-
-        $objects = array();
-        $query = 
-            'SELECT '.$columns.' '.
-            'FROM `'.MYSQL_PREFIX.'event` '.
-            'LEFT JOIN `'.MYSQL_PREFIX.'feed` '.
-            'ON (`'.MYSQL_PREFIX.'event`.`feed` = `'.MYSQL_PREFIX.'feed`.`id`) '.
-            $whereClause.' '.
-            'ORDER BY '.$order.' '.
-            'LIMIT '.$start.','.$limit;
-        $results = $this->customQuery($query);
-        if($results!=false){
-            while($item = $results->fetch_array()){
-                $object = new Event();
-                    foreach($object->getObject_fields() as $field=>$type){
-                        $setter = 'set'.ucFirst($field);
-                        if(isset($item[$field])) $object->$setter($item[$field]);
-                    }
-                    $objects[] = $object;
-                    unset($object);
-            }
-        }
-
-        return $objects;
-    }
-
-    function __construct(){
-        parent::__construct();
-    }
-
-    function setId($id){
-        $this->id = $id;
-    }
-
-    function getFeeds(){
-        $feedManager = new Feed();
-        return $feedManager->loadAll(array('folder'=>$this->getId()),'name');
-    }
-
-    function getFolders(){
-        $folderManager = new Folder();
-        return $folderManager->loadAll(array('parent'=>$this->getId()));
-    }
-
-
-    function getId(){
-        return $this->id;
-    }
-
-    function getName(){
-        return $this->name;
-    }
-
-    function setName($name){
-        $this->name = $name;
-    }
-
-    function getParent(){
-        return $this->parent;
-    }
-
-    function setParent($parent){
-        $this->parent = $parent;
-    }
-
-    function getIsopen(){
-        return $this->isopen;
-    }
-
-    function setIsopen($isopen){
-        $this->isopen = $isopen;
-    }
-
-
-
-}
-
-?>
diff --git a/leed/Functions.class.php b/leed/Functions.class.php
deleted file mode 100644
index d9bec5de027770805e37c7d7eb00bc7e603f458e..0000000000000000000000000000000000000000
--- a/leed/Functions.class.php
+++ /dev/null
@@ -1,405 +0,0 @@
-<?php
-
-/*
- @nom: constant
- @auteur: Idleman (http://blog.idleman.fr)
- @description:  Classe de stockage des fonctions utiles (toutes disponibles en static)
- */
-
-class Functions
-{
-    private $id;
-    public $debug=0;
-
-    /**
-     * Securise la variable utilisateur entrée en parametre
-     * @author Valentin
-     * @param<String> variable a sécuriser
-     * @param<Integer> niveau de securisation
-     * @return<String> variable securisée
-     */
-
-    public static function secure($var,$level = 1){
-        $var = htmlspecialchars($var, ENT_QUOTES, "UTF-8");
-        if($level<1)$var = mysqli_real_escape_string($var);
-        if($level<2)$var = addslashes($var);
-        return $var;
-    }
-
-
-    /**
-     * Return l'environnement/serveur sur lequel on se situe, permet de changer les
-     * connexions bdd en fonction de la dev, la préprod ou la prod
-     */
-    public static function whereImI(){
-
-        $maps = array (
-        'LOCAL'=>array('localhost','127.0.0.1','0.0.0.1','::0.0.0.0'),
-        'LAN'=>array('192.168.10.','valentin'),
-        'PWAN'=>array('test.sys1.fr'),
-        'WAN'=>array('www.sys1.fr'),
-        );
-
-
-        $return = 'UNKNOWN';
-        foreach($maps as $map=>$values){
-
-            foreach($values as $ip){
-                $pos = strpos(strtolower($_SERVER['HTTP_HOST']),$ip);
-                if ($pos!==false){
-                    $return = $map;
-                }
-            }
-        }
-        return $return;
-    }
-
-    public static function isLocal($perimeter='LOCAL'){
-        $return = false;
-
-        $localTab = array('localhost','127.0.0.1','0.0.0.1','::0.0.0.0');
-        $lanTab = array('192.168.10.','valentin');
-
-        switch($perimeter){
-            case 'LOCAL':
-                foreach($localTab as $ip){
-                    $pos = strpos(strtolower($_SERVER['HTTP_HOST']),$ip);
-                    if ($pos!==false){
-                        $return = true;
-                    }
-                }
-                break;
-            case 'LAN':
-                foreach($lanTab as $ip){
-                    $pos = strpos(strtolower($_SERVER['HTTP_HOST']),$ip);
-                    if ($pos!==false){
-                        $return = true;
-                    }
-                }
-                break;
-            case 'ALL':
-                foreach($localTab as $ip){
-                    $pos = strpos(strtolower($_SERVER['HTTP_HOST']),$ip);
-                    if ($pos!==false){
-                        $return = true;
-                    }
-                }
-                foreach($lanTab as $ip){
-                    $pos = strpos(strtolower($_SERVER['HTTP_HOST']),$ip);
-                    if ($pos!==false){
-                        $return = true;
-                    }
-                }
-                break;
-        }
-
-        return $return;
-    }
-
-
-    /**
-     * Convertis la chaine passée en timestamp quel que soit sont format
-     * (prend en charge les formats type dd-mm-yyy , dd/mm/yyy, yyyy/mm/ddd...)
-     */
-    public static function toTime($string){
-        $string = str_replace('/','-',$string);
-        $string = str_replace('\\','-',$string);
-
-        $string = str_replace('Janvier','Jan',$string);
-        $string = str_replace('Fevrier','Feb',$string);
-        $string = str_replace('Mars','Mar',$string);
-        $string = str_replace('Avril','Apr',$string);
-        $string = str_replace('Mai','May',$string);
-        $string = str_replace('Juin','Jun',$string);
-        $string = str_replace('Juillet','Jul',$string);
-        $string = str_replace('Aout','Aug',$string);
-        $string = str_replace('Septembre','Sept',$string);
-        $string = str_replace('Octobre','Oct',$string);
-        $string = str_replace('Novembre','Nov',$string);
-        $string = str_replace('Decembre','Dec',$string);
-        return strtotime($string);
-    }
-
-    /**
-     * Recupere l'ip de l'internaute courant
-     * @author Valentin
-     * @return<String> ip de l'utilisateur
-     */
-
-    public static function getIP(){
-        if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
-            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];}
-            elseif(isset($_SERVER['HTTP_CLIENT_IP'])){
-                $ip = $_SERVER['HTTP_CLIENT_IP'];}
-                else{ $ip = $_SERVER['REMOTE_ADDR'];}
-                return $ip;
-    }
-
-    /**
-     * Retourne une version tronquée au bout de $limit caracteres de la chaine fournie
-     * @author Valentin
-     * @param<String> message a tronquer
-     * @param<Integer> limite de caracteres
-     * @return<String> chaine tronquée
-     */
-    public static function truncate($msg,$limit){
-        $str = html_entity_decode($msg, ENT_QUOTES, 'UTF-8');
-        $count = preg_match_all('/\X/u', $str);
-        if($count<=$limit){
-            return $msg;
-        }
-        $fin='…' ;
-        $nb=$limit-1;
-        return htmlentities(mb_substr($str, 0, $nb, 'UTF-8').$fin);
-    }
-
-
-    function getExtension($fileName){
-        $dot = explode('.',$fileName);
-        return $dot[sizeof($dot)-1];
-    }
-
-    /**
-     * Definis si la chaine fournie est existante dans la reference fournie ou non
-     * @param unknown_type $string
-     * @param unknown_type $reference
-     * @return false si aucune occurence du string, true dans le cas contraire
-     */
-    public static function contain($string,$reference){
-        $return = true;
-        $pos = strpos($reference,$string);
-        if ($pos === false) {
-            $return = false;
-        }
-        return strtolower($return);
-    }
-
-    /**
-     * Définis si la chaine passée en parametre est une url ou non
-     */
-    public static function isUrl($url){
-        $return =false;
-        if (preg_match('/^(http|https|ftp)://([A-Z0-9][A-Z0-9_-]*(?:.[A-Z0-9][A-Z0-9_-]*)+):?(d+)?/?/i', $url)) {
-            $return =true;
-        }
-        return $return;
-    }
-
-    /**
-     * Définis si la chaine passée en parametre est une couleur héxadécimale ou non
-     */
-    public static function isColor($color){
-        $return =false;
-        if (preg_match('/^#(?:(?:[a-fd]{3}){1,2})$/i', $color)) {
-            $return =true;
-        }
-        return $return;
-    }
-
-    /**
-     * Définis si la chaine passée en parametre est un mail ou non
-     */
-    public static function isMail($mail){
-        $return =false;
-        if (filter_var($mail, FILTER_VALIDATE_EMAIL)) {
-            $return =true;
-        }
-        return $return;
-    }
-
-    /**
-     * Définis si la chaine passée en parametre est une IP ou non
-     */
-    public static function isIp($ip){
-        $return =false;
-        if (preg_match('^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:[.](?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$',$ip)) {
-            $return =true;
-        }
-        return $return;
-    }
-
-    public static function sourceName($string){
-        $name = strtolower($string);
-        $name = str_replace(' ','-',$name);
-        $name = str_replace('&#039;','-',$name);
-        $name = str_replace('\'','-',$name);
-        $name = str_replace(',','-',$name);
-        $name = str_replace(':','-',$name);
-        $name = str_replace('&agrave;','a',$name);
-        $name = trim($name);
-        $name = html_entity_decode($name,null,'UTF-8');
-        return $name;
-    }
-
-    public static function makeCookie($name, $value, $expire='') {
-        if($expire == '') {
-            setcookie($name, $value, mktime(0,0,0, date("d"),
-            date("m"), (date("Y")+1)),'/');
-        }else {
-            setcookie($name, '', mktime(0,0,0, date("d"),
-            date("m"), (date("Y")-1)),'/');
-        }
-    }
-
-    public static function destroyCookie($name){
-        Fonction::makeCookie($name,'',time()-3600);
-        unset($_COOKIE[$name]);
-    }
-
-    public static function wordwrap($str, $width = 75, $break = "\n", $cut = false)
-    {
-        $str = html_entity_decode($str);
-        $str =  htmlentities (wordwrap($str,$width,$break,$cut));
-        $str = str_replace('&lt;br/&gt;','<br/>',$str);
-        $str = str_replace('&amp;','&',$str);
-        return $str;
-    }
-
-    public static function createFile($filePath,$content){
-        $fichier = fopen($filePath,"w+");
-        $fwriteResult = fwrite($fichier,$content);
-        fclose($fichier);
-    }
-
-
-
-    public static function convertFileSize($bytes)
-    {
-         if($bytes<1024){
-             return round(($bytes / 1024), 2).' o';
-         }elseif(1024<$bytes && $bytes<1048576){
-             return round(($bytes / 1024), 2).' ko';
-         }elseif(1048576<$bytes && $bytes<1073741824){
-             return round(($bytes / 1024)/1024, 2).' Mo';
-         }elseif(1073741824<$bytes){
-             return round(($bytes / 1024)/1024/1024, 2).' Go';
-         }
-    }
-
-
-    public static function hexaValue($str){
-        $code = dechex(crc32($str));
-          $code = substr($code, 0, 6);
-          return $code;
-    }
-
-    public static function scanRecursiveDir($dir){
-        $files = scandir($dir);
-        $allFiles = array();
-        foreach($files as $file){
-            if($file!='.' && $file!='..'){
-                if(is_dir($dir.$file)){
-                    $allFiles = array_merge($allFiles,Fonction::scanRecursiveDir($dir.$file));
-                }else{
-                    $allFiles[]=str_replace('//','/',$dir.'/'.$file);
-                }
-            }
-        }
-        return $allFiles;
-    }
-
-    /** Permet la sortie directe de texte à l'écran, sans tampon.
-        Source : http://php.net/manual/fr/function.flush.php
-    */
-    public static function triggerDirectOutput() {
-        // La ligne de commande n'en a pas besoin.
-        if ('cli'==php_sapi_name()) return;
-        if (function_exists('apache_setenv')) {
-            /* Selon l'hébergeur la fonction peut être désactivée. Alors Php
-               arrête le programme avec l'erreur :
-               "PHP Fatal error:  Call to undefined function apache_setenv()".
-            */
-            @apache_setenv('no-gzip', 1);
-        }
-        @ini_set('zlib.output_compression', 0);
-        @ini_set('implicit_flush', 1);
-        for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
-        ob_implicit_flush(1);
-    }
-
-    public static function relativePath($from, $to, $ps = '/') {
-        $arFrom = explode($ps, rtrim($from, $ps));
-        $arTo = explode($ps, rtrim($to, $ps));
-        while(count($arFrom) && count($arTo) && ($arFrom[0] == $arTo[0])) {
-            array_shift($arFrom);
-            array_shift($arTo);
-        }
-        return str_pad("", count($arFrom) * 3, '..'.$ps).implode($ps, $arTo);
-    }
-
-
-    // Nettoyage de l'url avant la mise en base
-    public static function clean_url( $url ) {
-        $url = str_replace('&amp;', '&', $url);
-        return $url;
-    }
-
-
-
-    /**
-    * Méthode de test de connexion.
-    * @return true si ok
-    * @param server
-    * @param login
-    * @param pass
-    * @param db facultatif, si précisé alors tente de la séléctionner
-    */
-    public static function testDb($server, $login, $pass, $db=null) {
-        /* Méthode hors des classes dédiées aux BDD afin de supporter le moins
-           de dépendances possibles. En particulier, pas besoin que le fichier
-           de configuration existe. */
-        $link = mysqli_connect($server, $login, $pass, $db);
-        if (false===$link) return false;
-        $version = mysqli_get_server_version($link);
-        if( $version < 50503 ) return false;
-        mysqli_close($link);
-        return true;
-    }
-
-    /**
-    * @return boolean
-    */
-    public static function isAjaxCall() {
-        return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
-    }
-
-    /**
-    * Charge dans la portée locale des variables de $_REQUEST
-    * Ex: chargeVarRequest('liste', 'var') créera $liste et $var venant de $_REQUEST
-    */ 
-    public static function chargeVarRequest() {
-        foreach (func_get_args() as $arg) {
-            global ${$arg};
-            if (array_key_exists($arg, $_REQUEST)) {
-                $valeur = $_REQUEST[$arg];
-            } else {
-                $valeur = '';
-            }
-            ${$arg} = $valeur;
-        }
-    }
-
-    /**
-    * Vide le contenu du cache de RainTpl
-    *
-    */
-    public static function purgeRaintplCache() {
-        $directory = raintpl::$cache_dir;
-        if ($directory) {
-            $files = glob($directory.'*.rtpl.php');
-            if ($files) {
-                foreach($files as $file) {
-                    if (!unlink($file)) {
-                        error_log("Leed: cannot unlink '$file'");
-                    }
-                }
-            } else {
-                error_log('Leed: Raintpl, no file cached: '.$directory.'   '.getcwd());
-            }
-        } else {
-            error_log('Leed: Raintpl cache directory not set!');
-        }
-    }
-
-    }
-?>
diff --git a/leed/Install.class.php b/leed/Install.class.php
deleted file mode 100644
index 69fb3aee3a394aa9de45e3f42da649ecbb08b4f8..0000000000000000000000000000000000000000
--- a/leed/Install.class.php
+++ /dev/null
@@ -1,215 +0,0 @@
-<?php
-
-class Install {
-
-    const DEFAULT_TABLES_PREFIX = 'leed__';
-    const CONSTANT_FILE = 'constant.php';
-    public $finished = false;
-    public $logs = array(
-        'errors' => array(),
-        'notices' => array()
-    );
-    public $options = array(
-        'user' => array(
-            'login' => "",
-            'password' => ""
-        ),
-        'db' => array(
-            'mysqlBase' => "",
-            'mysqlHost' => "",
-            'mysqlLogin' => "",
-            'mysqlMdp' => "",
-            'mysqlPrefix' => self::DEFAULT_TABLES_PREFIX
-        )
-    );
-    protected $salt;
-
-
-    public function __construct() {
-        require_once('Logger.class.php');
-        $this->logger = new Logger('install');
-    }
-
-    protected function overrideDefaultValues($_) {
-        foreach ($this->options as $type => $options) {
-            foreach ($options as $var => $defaultValue) {
-                if (!empty($_[$var])) {
-                    $val = $type === 'db' ? str_replace("'", "\'", $_[$var]) : Functions::secure($_[$var]);
-                    $this->options[$type][$var] = $val;
-                }
-            }
-        }
-    }
-
-    public function launch($_, $installActionName) {
-        if (!$this->checkFunctionsExists()) {
-	        return false;
-        }
-        if(!isset($_[$installActionName])) {
-            return false;
-        }
-        $this->overrideDefaultValues($_);
-        $this->checkLoginPassword();
-        $this->checkdb();
-        if(!$this->hasErrors()) {
-            $this->createConstantFile();
-
-            require_once('constant.php');
-            require_once('MysqlEntity.class.php');
-            class_exists('Update') or require_once('Update.class.php');
-            Update::ExecutePatch(true);
-            require_once('Feed.class.php');
-            require_once('Event.class.php');
-            require_once('User.class.php');
-            require_once('Folder.class.php');
-            require_once('Configuration.class.php');
-
-            $this->createConfig();
-            $this->createUser();
-            $this->setFinished(true);
-            $this->logger->destroy();
-        }
-    }
-
-    public function getDefaultRoot() {
-        $urlParts = explode('/', $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);
-        array_pop($urlParts);
-        return implode('/', $urlParts);
-    }
-
-    protected function createConstantFile() {
-        $constant = "<?php
-//Host de Mysql, le plus souvent localhost ou 127.0.0.1
-define('MYSQL_HOST','{$this->options['db']['mysqlHost']}');
-//Identifiant MySQL
-define('MYSQL_LOGIN','{$this->options['db']['mysqlLogin']}');
-//mot de passe MySQL
-define('MYSQL_MDP','{$this->options['db']['mysqlMdp']}');
-//Nom de la base MySQL ou se trouvera leed
-define('MYSQL_BDD','{$this->options['db']['mysqlBase']}');
-//Prefix des noms des tables leed pour les bases de données uniques
-define('MYSQL_PREFIX','{$this->options['db']['mysqlPrefix']}');
-?>";
-
-        file_put_contents(self::CONSTANT_FILE, $constant);
-        if (!is_readable(self::CONSTANT_FILE))
-            die('"'.self::CONSTANT_FILE.'" not found!');
-    }
-
-    protected function createConfig() {
-        $configurationManager = new Configuration();
-        if ($configurationManager->tableExists()) {
-            $configurationManager->truncate();
-        }
-        $configurationManager->create();
-        $configurationManager->setDefaults();
-        $this->salt = $configurationManager->get('cryptographicSalt');
-    }
-
-    protected function createUser() {
-        $userManager = new User();
-        if ($userManager->tableExists()) {
-            $userManager->truncate();
-        }
-        $userManager->create();
-        $userManager->add($this->options['user']['login'], $this->options['user']['password'], $this->salt, $this->logger);
-        $_SESSION['currentUser'] = serialize($userManager->get($this->options['user']['login']));
-    }
-
-    protected function checkLoginPassword() {
-        if(
-            empty($this->options['user']['password'])
-            || empty($this->options['user']['login'])
-        ) {
-            $this->logs['errors'][] = _t('INSTALL_ERROR_USERPWD');
-            return false;
-        }
-        return true;
-    }
-
-    protected function checkDb() {
-        if(
-            empty($this->options['db']['mysqlHost'])
-            || empty($this->options['db']['mysqlLogin'])
-            || empty($this->options['db']['mysqlBase'])
-        ) {
-            $this->logs['errors'][] = _t('INSTALL_ERROR_DB_INFOS');
-            return false;
-        }
-        if (!Functions::testDb(
-            $this->options['db']['mysqlHost'], $this->options['db']['mysqlLogin'], $this->options['db']['mysqlMdp'], $this->options['db']['mysqlBase']
-        )) {
-            $this->logs['errors'][] = _t('INSTALL_ERROR_CONNEXION');
-        } else {
-            $this->logs['notices'][] = _t('INSTALL_INFO_CONNEXION');
-        }
-        return true;
-    }
-
-    public function hasErrors() {
-        return count($this->logs['errors']) > 0;
-    }
-
-    public function checkFunctionsExists() {
-        if(!is_writable('./')){
-            $this->logs['errors'][] = _t('INSTALL_ERROR_RIGHT', array(str_replace(basename(__FILE__),'',__FILE__)));
-        }else{
-            $this->logs['notices'][] = _t('INSTALL_INFO_RIGHT');
-        }
-        if (!@function_exists('simplexml_load_file')){
-            $this->logs['errors'][] = _t('INSTALL_ERROR_PHPXML');
-        }else{
-            $this->logs['notices'][] = _t('INSTALL_INFO_PHPXML');
-        }
-        if (!@function_exists('mysqli_connect')){
-            $this->logs['errors'][] = _t('INSTALL_ERROR_MYSQLICONNECT');
-        }else{
-            $this->logs['notices'][] = _t('INSTALL_INFO_MYSQLICONNECT');
-        }
-        if (!@function_exists('file_get_contents')){
-            $this->logs['errors'][] =  _t('INSTALL_ERROR_FILEGET');
-        }else{
-            $this->logs['notices'][] = _t('INSTALL_INFO_FILEGET');
-        }
-        if (!@function_exists('file_put_contents')){
-            $this->logs['errors'][] = _t('INSTALL_ERROR_FILEPUT');
-        }else{
-            $this->logs['notices'][] = _t('INSTALL_INFO_FILEPUT');
-        }
-        if (!@function_exists('curl_exec')){
-            $this->logs['errors'][] = _t('INSTALL_ERROR_CURL');
-        }else{
-            $this->logs['notices'][] = _t('INSTALL_INFO_CURL');
-        }
-        if (!@function_exists('gd_info')){
-            $this->logs['errors'][] = _t('INSTALL_ERROR_GD');
-        }else{
-            $this->logs['notices'][] = _t('INSTALL_INFO_GD');
-        }
-        if (!@function_exists('mb_internal_encoding')){
-            $this->logs['errors'][] = _t('INSTALL_ERROR_MB');
-        }else{
-            $this->logs['notices'][] = _t('INSTALL_INFO_MB');
-        }
-        if (@version_compare(PHP_VERSION, '7.2', '<')){
-            $this->logs['errors'][] = _t('INSTALL_ERROR_PHPV', array(PHP_VERSION));
-        }else{
-            $this->logs['notices'][] = _t('INSTALL_INFO_PHPV', array(PHP_VERSION));
-        }
-        if(ini_get('safe_mode') && ini_get('max_execution_time')!=0){
-            $this->logs['errors'][] = _t('INSTALL_ERROR_SAFEMODE');
-        }else{
-            $this->logs['notices'][] = _t('INSTALL_INFO_SAFEMODE');
-        }
-        return empty($this->logs['errors']);
-    }
-
-    public function setFinished($finished) {
-        $this->finished = $finished;
-
-    }
-
-    public function getFinished() {
-        return $this->finished;
-    }
-}
diff --git a/leed/License-AGPL-3.0.txt b/leed/License-AGPL-3.0.txt
deleted file mode 100644
index dba13ed2ddf783ee8118c6a581dbf75305f816a3..0000000000000000000000000000000000000000
--- a/leed/License-AGPL-3.0.txt
+++ /dev/null
@@ -1,661 +0,0 @@
-                    GNU AFFERO GENERAL PUBLIC LICENSE
-                       Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
-  A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate.  Many developers of free software are heartened and
-encouraged by the resulting cooperation.  However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
-  The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community.  It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server.  Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
-  An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals.  This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU Affero General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Remote Network Interaction; Use with the GNU General Public License.
-
-  Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software.  This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time.  Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Affero General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Affero General Public License for more details.
-
-    You should have received a copy of the GNU Affero General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source.  For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code.  There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-<http://www.gnu.org/licenses/>.
diff --git a/leed/Logger.class.php b/leed/Logger.class.php
deleted file mode 100644
index 5f8447b4a9437eb262ed940dc70983f19f38206d..0000000000000000000000000000000000000000
--- a/leed/Logger.class.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-
-class Logger {
-
-    CONST LOGGER_IDENTIFIER = 'logger';
-    protected $name;
-    protected $logs = array();
-
-    public function __construct($name = 'messages'){
-        $this->name = $name;
-    }
-
-    public function save(){
-        $_SESSION[self::LOGGER_IDENTIFIER][$this->getName()] = serialize($this->logs);
-    }
-
-    public function appendLogs($msg){
-        $this->logs[] = $msg;
-    }
-
-    public function flushLogs()
-    {
-        $logs = $this->getLogs();
-        $this->destroy();
-        return $logs;
-    }
-
-    public function destroy(){
-        unset($_SESSION[self::LOGGER_IDENTIFIER][$this->getName()]);
-    }
-
-    protected function mergeLogsInSession(){
-        if( isset($_SESSION[self::LOGGER_IDENTIFIER][$this->getName()])
-            || !empty($_SESSION[self::LOGGER_IDENTIFIER][$this->getName()])
-        ) {
-            $this->logs = array_unique(array_merge($this->logs, unserialize($_SESSION[self::LOGGER_IDENTIFIER][$this->getName()])));
-        }
-    }
-
-    public function hasLogs()
-    {
-        return count($this->logs) > 0;
-    }
-
-    public function setName($name)
-    {
-        $this->name = $name;
-    }
-
-    public function getName()
-    {
-        return $this->name;
-    }
-
-    public function setLogs($logs)
-    {
-        $this->logs = $logs;
-    }
-
-    public function getLogs()
-    {
-        $this->mergeLogsInSession();
-        return $this->logs;
-    }
-
-}
-
-?>
diff --git a/leed/MysqlConnector.class.php b/leed/MysqlConnector.class.php
deleted file mode 100644
index 126b0816626e4f9c5ed0ea32086c6527c837f410..0000000000000000000000000000000000000000
--- a/leed/MysqlConnector.class.php
+++ /dev/null
@@ -1,197 +0,0 @@
-<?php
-
-/*
-    @nom: mysql
-    @auteur: Idleman (http://blog.idleman.fr)
-    @date de création:
-    @description: Classe de gestion des connexions Mysql
-*/
-
-class MysqlConnector
-{
-    private $id;
-    private $hote;
-    private $login;
-    private $mdp;
-    private $bdd;
-    private $port;
-    public $debug=0;
-    public $connection = null;
-    public static $instance = null;
-
-    public function __construct(){
-        $this->connection = new mysqli(MYSQL_HOST,MYSQL_LOGIN,MYSQL_MDP,MYSQL_BDD);
-        $this->connection->set_charset('utf8mb4');
-        $this->connection->query('SET NAMES utf8mb4');
-    }
-
-
-
-    /**
-    * Methode de recuperation unique de l'instance
-    * @author Valentin CARRUESCO
-    * @category Singleton
-    * @param <Aucun>
-    * @return <mysql> $instance
-    */
-
-    public static function getInstance(){
-
-        if (MysqlConnector::$instance === null) {
-            MysqlConnector::$instance = new self();
-        }
-        return MysqlConnector::$instance;
-    }
-
-
-    public function __toString(){
-        $retour = "";
-        $retour .= "instance de la classe MysqlConnector : <br/>";
-        $retour .= '$hote : '.$this->hote.'<br/>';
-        $retour .= '$login : '.$this->login.'<br/>';
-        $retour .= '$mdp : '.$this->mdp.'<br/>';
-        $retour .= '$bdd : '.$this->bdd.'<br/>';
-        $retour .= '$port : '.$this->port.'<br/>';
-        return $retour;
-    }
-
-    private  function __clone(){
-        //Action lors du clonage de l'objet
-    }
-
-    // ACCESSEURS
-
-    public function getId(){
-        return $this->id;
-    }
-
-    public function setId($id){
-        $this->id = $id;
-    }
-
-    /**
-    * Méthode de récuperation de l'attribut hote de la classe Mysql
-    * @author Valentin CARRUESCO
-    * @category Accesseur
-    * @param Aucun
-    * @return <Attribute> hote
-    */
-
-    public function getHote(){
-        return $this->hote;
-    }
-
-    /**
-    * Méthode de définition de l'attribut hote de la classe Mysql
-    * @author Valentin CARRUESCO
-    * @category Accesseur
-    * @param <Attribute> $hote
-    * @return Aucun retour
-    */
-
-    public function setHote($hote){
-        $this->hote = $hote;
-    }
-
-    /**
-    * Méthode de récuperation de l'attribut login de la classe Mysql
-    * @author Valentin CARRUESCO
-    * @category Accesseur
-    * @param Aucun
-    * @return <Attribute> login
-    */
-
-    public function getLogin(){
-        return $this->login;
-    }
-
-    /**
-    * Méthode de définition de l'attribut login de la classe Mysql
-    * @author Valentin CARRUESCO
-    * @category Accesseur
-    * @param <Attribute> $login
-    * @return Aucun retour
-    */
-
-    public function setLogin($login){
-        $this->login = $login;
-    }
-
-    /**
-    * Méthode de récuperation de l'attribut mdp de la classe Mysql
-    * @author Valentin CARRUESCO
-    * @category Accesseur
-    * @param Aucun
-    * @return <Attribute> mdp
-    */
-
-    public function getMdp(){
-        return $this->mdp;
-    }
-
-    /**
-    * Méthode de définition de l'attribut mdp de la classe Mysql
-    * @author Valentin CARRUESCO
-    * @category Accesseur
-    * @param <Attribute> $mdp
-    * @return Aucun retour
-    */
-
-    public function setMdp($mdp){
-        $this->mdp = $mdp;
-    }
-
-    /**
-    * Méthode de récuperation de l'attribut bdd de la classe Mysql
-    * @author Valentin CARRUESCO
-    * @category Accesseur
-    * @param Aucun
-    * @return <Attribute> bdd
-    */
-
-    public function getBdd(){
-        return $this->bdd;
-    }
-
-    /**
-    * Méthode de définition de l'attribut bdd de la classe Mysql
-    * @author Valentin CARRUESCO
-    * @category Accesseur
-    * @param <Attribute> $bdd
-    * @return Aucun retour
-    */
-
-    public function setBdd($bdd){
-        $this->bdd = $bdd;
-    }
-
-    /**
-    * Méthode de récuperation de l'attribut port de la classe Mysql
-    * @author Valentin CARRUESCO
-    * @category Accesseur
-    * @param Aucun
-    * @return <Attribute> port
-    */
-
-    public function getPort(){
-        return $this->port;
-    }
-
-    /**
-    * Méthode de définition de l'attribut port de la classe Mysql
-    * @author Valentin CARRUESCO
-    * @category Accesseur
-    * @param <Attribute> $port
-    * @return Aucun retour
-    */
-
-    public function setPort($port){
-        $this->port = $port;
-    }
-
-    public function error() {
-        return mysqli_error($this->connection);
-    }
-
-}
-?>
diff --git a/leed/MysqlEntity.class.php b/leed/MysqlEntity.class.php
deleted file mode 100644
index d57ada97ce06413489bf3a1bff91ec6aec3b8fdb..0000000000000000000000000000000000000000
--- a/leed/MysqlEntity.class.php
+++ /dev/null
@@ -1,484 +0,0 @@
-<?php
-require_once('constant.php');
-require_once('MysqlConnector.class.php');
-/*
-    @nom: MysqlEntity
-    @auteur: Valentin CARRUESCO (valentincarruesco@yahoo.fr)
-    @date de création: 16/04/2012 02:34:15
-    @description: Classe parent de tous les modèles (classe entitées) liées a la base de donnée,
-     cette classe est configuré pour agir avec une base MySQL, mais il est possible de redefinir ses codes SQL pour l'adapter à un autre SGBD sans affecter
-     le reste du code du projet.
-
-*/
-
-class MysqlEntity
-{
-
-    protected $dbconnector = false;
-    private $debug = false;
-    private $debugAllQuery = false;
-
-
-    function sgbdType($type){
-        $return = false;
-        switch($type){
-            case 'string':
-            case 'timestamp':
-                $return = 'VARCHAR(225) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci';
-            break;
-            case 'longstring':
-                $return = 'TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci';
-            break;
-            case 'extralongstring':
-                $return = 'MEDIUMTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci';
-                break;
-            case 'key':
-                $return = 'int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY';
-            break;
-            case 'object':
-            case 'integer':
-                $return = 'INT(11)';
-            break;
-            case 'boolean':
-                $return = 'INT(1)';
-            break;
-            default;
-                $return = 'TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci';
-            break;
-        }
-        return $return ;
-    }
-
-    /**
-     * Protège une variable pour MySQL
-     */
-    protected function secure($value, $field){
-        $type = false;
-
-        // ce champ n'existe pas : on le considère comme une chaîne de caractères
-        if (isset($this->object_fields[$field]))
-            $type = $this->object_fields[$field];
-
-        $return = false;
-        switch($type){
-            case 'key':
-            case 'object':
-            case 'integer':
-            case 'boolean':
-                $return = intval($value);
-            break;
-            case 'string':
-            case 'timestamp':
-            case 'longstring':
-            default;
-                $return = $this->dbconnector->connection->real_escape_string((string)$value);
-            break;
-        }
-        return $return ;
-    }
-
-    public function __construct(){
-        $this->dbconnector = MysqlConnector::getInstance();
-    }
-
-    public function __destruct(){
-
-    }
-
-    // GESTION SQL
-
-    /**
-    * Methode de suppression de l'entité
-    * @author Valentin CARRUESCO
-    * @category manipulation SQL
-    * @return Aucun retour
-    */
-    public function destroy()
-    {
-        $query = 'DROP TABLE IF EXISTS `'.MYSQL_PREFIX.$this->TABLE_NAME.'`;';
-        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
-        $myQuery = $this->customQuery($query);
-    }
-
-    /**
-    * Methode de nettoyage de l'entité
-    * @author Valentin CARRUESCO
-    * @category manipulation SQL
-    * @return Aucun retour
-    */
-    public function truncate()
-    {
-        $query = 'TRUNCATE TABLE `'.MYSQL_PREFIX.$this->TABLE_NAME.'`;';
-        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
-        $myQuery = $this->customQuery($query);
-    }
-
-    /**
-    * Methode de creation de l'entité
-    * @author Valentin CARRUESCO
-    * @category manipulation SQL
-    * @return Aucun retour
-    */
-    public function create(){
-        $query = 'CREATE TABLE IF NOT EXISTS `'.MYSQL_PREFIX.$this->TABLE_NAME.'` (';
-
-        $i=false;
-        foreach($this->object_fields as $field=>$type){
-            if($i){$query .=',';}else{$i=true;}
-            $query .='`'.$field.'`  '. $this->sgbdType($type).'  NOT NULL';
-        }
-        if (isset($this->object_fields_index)){
-            foreach($this->object_fields_index as $field=>$type){
-                $query .= ',KEY `index'.$field.'` (`'.$field.'`)';
-            }
-        }
-        if (isset($this->object_fields_uniques)){
-            foreach($this->object_fields_uniques as $field){
-                $query .= ',UNIQUE `unique'.$field.'` (`'.$field.'`)';
-            }
-        }
-        $query .= ')
-        ENGINE InnoDB,
-        DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci
-        ;';
-        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
-        $myQuery = $this->customQuery($query);
-    }
-
-    public function massiveInsert($events){
-        if (empty($events)) return;
-        $query = 'INSERT INTO `'.MYSQL_PREFIX.$this->TABLE_NAME.'`(';
-            $i=false;
-            foreach($this->object_fields as $field=>$type){
-                if($type!='key'){
-                    if($i){$query .=',';}else{$i=true;}
-                    $query .='`'.$field.'`';
-                }
-            }
-            $query .=') select';
-            $u = false;
-
-            foreach($events as $event){
-
-                if($u){$query .=' union select ';}else{$u=true;}
-
-                $i=false;
-                foreach($event->object_fields as $field=>$type){
-                    if($type!='key'){
-                        if($i){$query .=',';}else{$i=true;}
-                        $query .='\''.$this->secure($event->$field, $field).'\'';
-                    }
-                }
-
-
-            }
-
-            $query .=';';
-            if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
-
-        $this->customQuery($query);
-    }
-
-    /**
-    * Methode d'insertion ou de modifications d'elements de l'entité
-    * @author Valentin CARRUESCO
-    * @category manipulation SQL
-    * @param  Aucun
-    * @return Aucun retour
-    */
-    public function save($id_field='id'){
-        if(isset($this->$id_field)){
-            $query = 'UPDATE `'.MYSQL_PREFIX.$this->TABLE_NAME.'`';
-            $query .= ' SET ';
-
-            $i=false;
-            foreach($this->object_fields as $field=>$type){
-                if($i){$query .=',';}else{$i=true;}
-                $id = $this->$field;
-                $query .= '`'.$field.'`=\''.$this->secure($id, $field).'\'';
-            }
-
-            $query .= ' WHERE `'.$id_field.'`=\''.$this->$id_field.'\';';
-        }else{
-            $query = 'INSERT INTO `'.MYSQL_PREFIX.$this->TABLE_NAME.'`(';
-            $i=false;
-            foreach($this->object_fields as $field=>$type){
-                if($i){$query .=',';}else{$i=true;}
-                $query .='`'.$field.'`';
-            }
-            $query .=')VALUES(';
-            $i=false;
-            foreach($this->object_fields as $field=>$type){
-                if($i){$query .=',';}else{$i=true;}
-                $query .='\''.$this->secure($this->$field, $field).'\'';
-            }
-
-            $query .=');';
-        }
-        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
-        $this->customQuery($query);
-        $this->$id_field =  (!isset($this->$id_field)?$this->dbconnector->connection->insert_id:$this->$id_field);
-    }
-
-    /**
-    * Méthode de modification d'éléments de l'entité
-    * @author Valentin CARRUESCO
-    * @category manipulation SQL
-    * @param <Array> $colonnes=>$valeurs
-    * @param <Array> $colonnes (WHERE) =>$valeurs (WHERE)
-    * @param <String> $operation="=" definis le type d'operateur pour la requete select
-    * @return Aucun retour
-    */
-    public function change($columns,$columns2,$operation='='){
-        $query = 'UPDATE `'.MYSQL_PREFIX.$this->TABLE_NAME.'` SET ';
-        $i=false;
-        foreach ($columns as $column=>$value){
-            if($i){$query .=',';}else{$i=true;}
-            $query .= '`'.$column.'`=\''.$this->secure($value, $column).'\' ';
-        }
-        $query .= $this->getWhereClause($columns2, $operation);
-
-        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
-        $this->customQuery($query);
-    }
-
-    /**
-    * Méthode de selection de tous les elements de l'entité
-    * @author Valentin CARRUESCO
-    * @category manipulation SQL
-    * @param <String> $ordre=null
-    * @param <String> $limite=null
-    * @return <Array<Entity>> $Entity
-    */
-    public function populate($order=null,$limit=null){
-        $results = $this->loadAll(array(),$order,$limit,'=');
-        return $results;
-    }
-
-    /**
-    * Méthode de selection multiple d'elements de l'entité
-    * @author Valentin CARRUESCO
-    * @category manipulation SQL
-    * @param <Array> $colonnes (WHERE)
-    * @param <Array> $valeurs (WHERE)
-    * @param <String> $ordre=null
-    * @param <String> $limite=null
-    * @param <String> $operation="=" definis le type d'operateur pour la requete select
-    * @return <Array<Entity>> $Entity
-    */
-    public function loadAll($columns,$order=null,$limit=null,$operation="=",$selColumn='*'){
-        $objects = array();
-        $whereClause = $this->getWhereClause($columns,$operation);
-
-            $query = 'SELECT '.$selColumn.' FROM `'.MYSQL_PREFIX.$this->TABLE_NAME.'` '.$whereClause.' ';
-            if($order!=null) $query .='ORDER BY '.$order.' ';
-            if($limit!=null) $query .='LIMIT '.$limit.' ';
-            $query .=';';
-
-            if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
-            $result = $this->customQuery($query);
-            if ($result)
-                while($queryReturn = $result->fetch_assoc()){
-                    $thisClass = get_class($this);
-                    $object = new $thisClass();
-                    foreach($this->object_fields as $field=>$type){
-                        if(isset($queryReturn[$field])) $object->$field = $queryReturn[$field];
-                    }
-                    $objects[] = $object;
-                    unset($object);
-                }
-            return $objects;
-    }
-
-    public function loadAllOnlyColumn($selColumn,$columns,$order=null,$limit=null,$operation="="){
-        $objects = $this->loadAll($columns,$order,$limit,$operation,$selColumn);
-        if(count($objects)==0)$objects = array();
-        return $objects;
-    }
-
-
-    /**
-    * Méthode de selection unique d'élements de l'entité
-    * @author Valentin CARRUESCO
-    * @category manipulation SQL
-    * @param <Array> $colonnes (WHERE)
-    * @param <Array> $valeurs (WHERE)
-    * @param <String> $operation="=" definis le type d'operateur pour la requete select
-    * @return <Entity> $Entity ou false si aucun objet n'est trouvé en base
-    */
-    public function load($columns,$operation='='){
-        $objects = $this->loadAll($columns,null,1,$operation);
-        if(!isset($objects[0]))$objects[0] = false;
-        return $objects[0];
-    }
-
-    /**
-    * Méthode de selection unique d'élements de l'entité
-    * @author Valentin CARRUESCO
-    * @category manipulation SQL
-    * @param <Array> $colonnes (WHERE)
-    * @param <Array> $valeurs (WHERE)
-    * @param <String> $operation="=" definis le type d'operateur pour la requete select
-    * @return <Entity> $Entity ou false si aucun objet n'est trouvé en base
-    */
-    public function getById($id,$operation='='){
-        return $this->load(array('id'=>$id),$operation);
-    }
-
-    /**
-    * Methode de comptage des éléments de l'entité
-    * @author Valentin CARRUESCO
-    * @category manipulation SQL
-    * @return<Integer> nombre de ligne dans l'entité'
-    */
-    public function rowCount($columns=null)
-    {
-        $whereClause ='';
-        if($columns!=null){
-            $whereClause = ' WHERE ';
-            $i=false;
-            foreach($columns as $column=>$value){
-                if($i){$whereClause .=' AND ';}else{$i=true;}
-                $whereClause .= '`'.$column.'`=\''.$this->secure($value, $column).'\'';
-            }
-        }
-        $query = 'SELECT COUNT(1) FROM `'.MYSQL_PREFIX.$this->TABLE_NAME.'`'.$whereClause;
-        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
-        $myQuery = $this->customQuery($query);
-        $number = $myQuery->fetch_array();
-        return $number[0];
-    }
-
-    /**
-    * Méthode de suppression d'éléments de l'entité
-    * @author Valentin CARRUESCO
-    * @category manipulation SQL
-    * @param <Array> $colonnes (WHERE)
-    * @param <Array> $valeurs (WHERE)
-    * @param <String> $operation="=" definis le type d'operateur pour la requete select
-    * @return Aucun retour
-    */
-    public function delete($columns,$operation='='){
-        $whereClause = '';
-
-        $i=false;
-        foreach($columns as $column=>$value){
-            if($i){$whereClause .=' AND ';}else{$i=true;}
-            $whereClause .= '`'.$column.'`'.$operation.'\''.$this->secure($value, $column).'\'';
-        }
-        $query = 'DELETE FROM `'.MYSQL_PREFIX.$this->TABLE_NAME.'` WHERE '.$whereClause.' ;';
-        if($this->debug)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$query.'<br>'.$this->dbconnector->connection->error;
-        $this->customQuery($query);
-
-    }
-
-    public function customQuery($request){
-        if($this->debugAllQuery)echo '<hr>'.get_class($this).' ('.__METHOD__ .') : Requete --> '.$request.'<br>'.$this->dbconnector->connection->error;
-        $result = $this->dbconnector->connection->query($request);
-        $error = $this->error();
-        if ($error) {
-            error_log('Leed error: '.$this->error());
-            error_log('Leed query: '.$request);
-        }
-        return $result;
-    }
-
-
-    // ACCESSEURS
-        /**
-    * Méthode de récuperation de l'attribut debug de l'entité
-    * @author Valentin CARRUESCO
-    * @category Accesseur
-    * @param Aucun
-    * @return <Attribute> debug
-    */
-
-    public function getDebug(){
-        return $this->debug;
-    }
-
-    /**
-    * Méthode de définition de l'attribut debug de l'entité
-    * @author Valentin CARRUESCO
-    * @category Accesseur
-    * @param <boolean> $debug
-    */
-
-    public function setDebug($debug){
-        $this->debug = $debug;
-    }
-
-    public function getObject_fields(){
-        return $this->object_fields;
-    }
-
-    /**
-    * @return <boolean> VRAI si la table existe, FAUX sinon
-    */
-
-    public function tableExists() {
-        $table = MYSQL_PREFIX.$this->TABLE_NAME;
-        $result = $this->customQuery("SHOW TABLES LIKE '$table'");
-        $assoc = $result->fetch_assoc();
-        return !is_null($assoc);
-    }
-
-    /**
-    * Protège les requêtes contre l'injection
-    */
-    public function escape_string($argument) {
-        return $this->dbconnector->connection->escape_string($argument);
-    }
-
-
-    /**
-    * Méthode de récupération d'un opérateur défini dans la valeur d'un filtre avant réquête
-    * @author Simon Alberny
-    * @param <str> Opérateur (ex. : '=', '!=', '<', '<=', '>', '>=')
-    * @param <str> Valeur ou opérateur valeur (ex. : '1', '< 1')
-    * @return <array> 0: opérateur, 1: valeur
-    */
-    protected function getCustomQueryOperator($operation_default, $value) {
-        $valid_operators = array('=','!=','<','<=','>','>=');
-        $operation = $operation_default;
-
-        // Modification de l'opération si contenu dans la valeur du filtre
-        $value_list = explode(' ', $value);
-        if((count($value_list) > 0) && (in_array($value_list[0],$valid_operators))) {
-            $operation = $value_list[0];
-            $value = $value_list[1];
-        }
-
-        return array($operation, $value);
-    }
-
-    /**
-    * Définition des clauses du WHERE dans une requête à la base de données
-    * @author Simon Alberny
-    * @param <array> Tableau de correspondance colonne => valeur (ex. : array( 'column' => 'value', 'column2' => '!= 2' ) )
-    * @param <str> Opérateur (ex. : '=', '!=', '<', '<=', '>', '>=')
-    * @return <str> WHERE...
-    */
-    protected function getWhereClause($columns,$operation) {
-        $whereClause = '';
-        $operation_default = $operation;
-
-        if($columns!=null && sizeof($columns)!=0){
-            $whereClause .= ' WHERE ';
-            $i = false;
-            foreach($columns as $column=>$value){
-                $customQueryOperator = $this->getCustomQueryOperator($operation_default, $value);
-                if($i){$whereClause .=' AND ';}else{$i=true;}
-                $whereClause .= '`'.$column.'`'.$customQueryOperator[0].'\''.$this->secure($customQueryOperator[1], $column).'\'';
-            }
-        }
-
-        return $whereClause;
-    }
-
-    public function error() {
-        return $this->dbconnector->error();
-    }
-
-}
-?>
diff --git a/leed/Opml.class.php b/leed/Opml.class.php
deleted file mode 100644
index dba0cd26242d5e13cde7bf90e9add8b1d54febb7..0000000000000000000000000000000000000000
--- a/leed/Opml.class.php
+++ /dev/null
@@ -1,167 +0,0 @@
-<?php
-
-/*
- @nom: Opml
- @auteur: Sbgodin (christophe.henry@sbgodin.fr)
- @description: Classe de gestion de l'import/export au format OPML
- */
-
-require_once("common.php");
-
-class Opml  {
-
-    // liens déjà connus, déjà abonnés, au moment de l'importation
-    public $alreadyKnowns = array();
-
-    /**
-     * Met à jour les données des flux.
-     */
-    protected function update() {
-        global $feedManager, $folderManager;
-        $this->feeds = $feedManager->populate('name');
-        $this->folders = $folderManager->loadAll(array('parent'=>-1),'name');
-    }
-
-    /**
-     * Convertit les caractères qui interfèrent avec le XML
-     */
-    protected function escapeXml($string) {
-        /** Les entités sont utiles pour deux raisons : encodage et
-        échappement. L'encodage n'est pas un problème, l'application travaille
-        nativement avec Unicode. L'échappement dans XML impose d'échapper les
-        esperluettes (&) et les guillemets. Ces derniers sont utilisés comme
-        séparateur de chaine. Les simples cotes restent intactes.
-        * On retire toutes les entités de sorte à obtenir une chaîne totalement
-          en UTF-8. Elle peut alors contenir des & et des ", nocifs pour XML.
-        * On échappe les caractères & et " de sorte à ce que le contenu dans le
-          XML soit correct. On suppose qu'à la lecture, cet échappement est
-          annulé.
-        * Accessoirement, on remplace les espaces non signifiants par une seule
-          espace. C'est le cas des retours chariots physiques, non
-          interprétables.
-        */
-        // Retire toutes les entités, &amp; &eacute; etc.
-        $string = html_entity_decode($string, ENT_COMPAT, 'UTF-8' );
-        // Remet les entités HTML comme &amp; mais ne touche pas aux accents.
-         $string = htmlspecialchars($string, ENT_COMPAT, 'UTF-8');
-         // Supprime les blancs non signifiants comme les sauts de ligne.
-         $string = preg_replace('/\s+/', ' ', $string);
-        return $string;
-    }
-
-    /**
-     * Exporte récursivement les flux.
-     */
-    protected function exportRecursive($folders, $identLevel=0) {
-        $_ = '  ';
-        $__ = ''; for($i=0;$i<$identLevel;$i++) $__.=$_;
-        $xmlStream = '';
-        foreach($folders as $folder) {
-            // Pas utilisé, vu qu'il n'y a qu'un seul niveau de dossiers.
-              $xmlStream .= $this->exportRecursive(
-                $folder->getFolders(), $identLevel+1
-            );
-            $feeds = $folder->getFeeds();
-            if (empty($feeds)) continue;
-            $text = $this->escapeXml($folder->getName());
-            $xmlStream .= "{$__}<outline text=\"$text\">\n";
-            foreach($feeds as $feed){
-                $url = $this->escapeXml($feed->getUrl());
-                $website = $this->escapeXml($feed->getWebsite());
-                $title = $this->escapeXml($feed->getName());
-                $text = $title;
-                $description = $this->escapeXml($feed->getDescription());
-                $xmlStream .= "{$__}{$_}<outline "
-                ."type=\"rss\" "
-                ."xmlUrl=\"$url\" "
-                ."htmlUrl=\"$website\" "
-                ."text=\"$text\" "
-                ."title=\"$title\" "
-                ."description=\"$description\""
-                ."/>\n";
-            }
-            $xmlStream .= "{$__}</outline>\n";
-        }
-        return $xmlStream;
-    }
-
-    /**
-     * Exporte l'ensemble des flux et sort les en-têtes.
-     */
-    function export() {
-        $this->update();
-        $date = date('D, d M Y H:i:s O');
-        $xmlStream = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
-<opml version=\"2.0\">
-  <head>
-    <title>Leed export</title>
-    <ownerName>Leed</ownerName>
-    <dateCreated>$date</dateCreated>
-  </head>
-  <body>\n";
-        $xmlStream .= $this->exportRecursive($this->folders, 2);
-        $xmlStream .= "  </body>\n</opml>\n";
-        return $xmlStream;
-    }
-
-    protected function importRec($folder, $folderId=1){
-        $folderManager = new Folder();
-        $feedManager = new Feed();
-        foreach($folder as $item) {
-            // Cela varie selon les implémentations d'OPML.
-            $feedName = $item['text'] ? 'text' : 'title';
-            if (isset($item->outline[0])) { // un dossier
-                $folder = $folderManager->load(array('name'=>$item[$feedName]));
-                $folder = (!$folder?new Folder():$folder);
-                $folder->setName($item[$feedName]);
-                $folder->setParent(($folderId==1?-1:$folderId));
-                $folder->setIsopen(0);
-                if($folder->getId()=='') $folder->save();
-                $this->importRec($item->outline,$folder->getId());
-            } else { // un flux
-                $newFeed = $feedManager->load(array('url'=>$item[0]['xmlUrl']));
-                $newFeed = (!$newFeed?new Feed():$newFeed);
-                if($newFeed->getId()=='') {
-                    /* Ne télécharge pas à nouveau le même lien, même s'il est
-                       dans un autre dossier. */
-                    $newFeed->setName($item[0][$feedName]);
-                    $newFeed->setUrl($item[0]['xmlUrl']);
-                    $newFeed->setDescription($item[0]['description']);
-                    $newFeed->setWebsite($item[0]['htmlUrl']);
-                    $newFeed->setFolder($folderId);
-                    $newFeed->save();
-                    // $newFeed->parse();
-                } else {
-                    $this->alreadyKnowns[]= (object) array(
-                        'description' => $newFeed->getDescription(),
-                        'feedName' => $newFeed->getName(),
-                        'xmlUrl' => $newFeed->getUrl()
-                    );
-                }
-            }
-        }
-    }
-
-    /**
-     * Importe les flux.
-     */
-    function import() {
-        require_once("SimplePie.class.php");
-        $file = $_FILES['newImport']['tmp_name'];
-        $internalErrors = libxml_use_internal_errors(true);
-        $xml = @simplexml_load_file($file);
-        $errorOutput = array();
-        foreach (libxml_get_errors() as $error) {
-            $errorOutput []= "{$error->message} (line {$error->line})";
-        }
-        libxml_clear_errors();
-        libxml_use_internal_errors($internalErrors);
-        if (!empty($xml) && empty($errorOutput)) {
-            $this->importRec($xml->body->outline);
-        }
-        return $errorOutput;
-    }
-
-}
-
-?>
diff --git a/leed/Plugin.class.php b/leed/Plugin.class.php
deleted file mode 100644
index dad8d76cbb61847a7a9074bb336501c008aacdeb..0000000000000000000000000000000000000000
--- a/leed/Plugin.class.php
+++ /dev/null
@@ -1,475 +0,0 @@
-<?php
-
-/*
- @nom: Plugin
- @auteur: Valentin CARRUESCO (http://blog.idleman.fr)
- @description: Classe de gestion des plugins au travers de l'application
- */
-
-class Plugin{
-
-    const FOLDER = '/plugins';
-    protected $name,$author,$address,$link,$licence,$path,$description,$version,$state,$type;
-
-    function __construct(){
-    }
-
-    public static function includeAll(){
-        global $i18n, $i18n_js, $theme;
-        $pluginFiles = Plugin::getFiles(true);
-        if(is_array($pluginFiles)) {
-            foreach($pluginFiles as $pluginFile) {
-                // Chargement du fichier de Langue du plugin
-                $i18n->append(new Translation(dirname($pluginFile),$i18n->languages));
-                // Inclusion du coeur de plugin
-                include $pluginFile;
-                // Gestion des css du plugin en fonction du thème actif
-                $cssTheme = glob(dirname($pluginFile).'/*/'.$theme.'.css');
-                $cssDefault = glob(dirname($pluginFile).'/*/default.css');
-                if(isset($cssTheme[0])){
-                    $GLOBALS['hooks']['css_files'][] = Functions::relativePath(str_replace('\\','/',dirname(__FILE__)),str_replace('\\','/',$cssTheme[0]));
-                }else if(isset($cssDefault[0])){
-                    $GLOBALS['hooks']['css_files'][] = Functions::relativePath(str_replace('\\','/',dirname(__FILE__)),str_replace('\\','/',$cssDefault[0]));
-                }
-            }
-        }
-        $i18n_js = $i18n->getJson();
-    }
-
-    private static function getStates(){
-        $stateFile = dirname(__FILE__).Plugin::FOLDER.'/plugins.states.json';
-        if(!file_exists($stateFile)) touch($stateFile);
-        return json_decode(file_get_contents($stateFile),true);
-    }
-    private static function setStates($states){
-        $stateFile = dirname(__FILE__).Plugin::FOLDER.'/plugins.states.json';
-        file_put_contents($stateFile,json_encode($states));
-    }
-    public static function pruneStates() {
-        $statesBefore = self::getStates();
-        if(empty($statesBefore))
-            $statesBefore = array();
-
-        $statesAfter = array();
-        $error = false;
-        if (is_array($statesBefore))
-        {
-            foreach($statesBefore as $file=>$state) {
-                if (file_exists($file))
-                    $statesAfter[$file] = $state;
-                else
-                    $error = true;
-            }
-        }
-        if ($error) self::setStates($statesAfter);
-    }
-
-
-    private static function getObject($pluginFile){
-        $plugin = new Plugin();
-        $fileLines = file_get_contents($pluginFile);
-
-        if(preg_match_all("#@author\s(.+)\s\<(.*)\>#", $fileLines, $matches)) {
-            foreach($matches[1] as $match) {
-                $authors[] = trim($match);
-            }
-            $plugin->setAuthor($authors);
-
-            foreach($matches[2] as $match) {
-                $address[] = strtolower($match);
-            }
-            $plugin->setAddress($address);
-        }
-
-        if(preg_match("#@name\s(.+)[\r\n]#", $fileLines, $match))
-            $plugin->setName($match[1]);
-
-        if(preg_match("#@licence\s(.+)[\r\n]#", $fileLines, $match))
-            $plugin->setLicence($match[1]);
-
-        if(preg_match("#@version\s(.+)[\r\n]#", $fileLines, $match))
-            $plugin->setVersion($match[1]);
-
-        if(preg_match("#@link\s(.+)[\r\n]#", $fileLines, $match))
-            $plugin->setLink(trim($match[1]));
-
-        if(preg_match("#@type\s(.+)[\r\n]#", $fileLines, $match))
-            $plugin->setType(trim($match[1]));
-
-        if(preg_match("#@description\s(.+)[\r\n]#", $fileLines, $match))
-            $plugin->setDescription(trim($match[1]));
-
-        if(Plugin::loadState($pluginFile) || $plugin->getType()=='component'){
-            $plugin->setState(1);
-        }else{
-            $plugin->setState(0);
-        }
-        $plugin->setPath($pluginFile);
-        return $plugin;
-    }
-
-    public static function getAll(){
-        $pluginFiles = Plugin::getFiles();
-
-        $plugins = array();
-        if(is_array($pluginFiles)) {
-            foreach($pluginFiles as $pluginFile) {
-                $plugin = Plugin::getObject($pluginFile);
-                $plugins[]=$plugin;
-            }
-        }
-        usort($plugins, "Plugin::sortPlugin");
-        return $plugins;
-    }
-
-    public static function install($url) {
-        $logger = new Logger('settings');
-        if(empty($url)){
-            $logger->appendLogs("Pas d'url renseignée.");
-        }elseif(filter_var($url, FILTER_VALIDATE_URL) === false){
-            $logger->appendLogs("L'url renseignée n'est pas valide.");
-        }else{
-            $logger->appendLogs('Téléchargement du plugin...');
-            $pluginBaseFolder = str_replace('/', '', self::FOLDER).'/';
-            $tempZipName = $pluginBaseFolder.md5(microtime());
-            file_put_contents($tempZipName,self::getUrlContent(urldecode($url)));
-            if(file_exists($tempZipName)){
-                $logger->appendLogs('Plugin téléchargé <span class="button notice">OK</span>');
-                $logger->appendLogs('Extraction du plugin...');
-                $zip = new ZipArchive;
-                $res = $zip->open($tempZipName);
-                if ($res === TRUE) {
-                    $tempZipFolder = $tempZipName.'_';
-                    $pluginFolder = $tempZipFolder;
-                    $zip->extractTo($tempZipFolder);
-                    $zip->close();
-                    $logger->appendLogs('Plugin extrait <span class="button notice">OK</span>');
-                    $fi = new FilesystemIterator($tempZipFolder, FilesystemIterator::SKIP_DOTS);
-                    if(iterator_count($fi) === 1) {
-                        foreach($fi as $file){
-                            $filename = $file->getFilename();
-                            $pluginFolder = $pluginBaseFolder.$filename;
-                            rename($tempZipFolder.'/'.$filename, $pluginFolder);
-                            rmdir($tempZipFolder);
-                        }
-                    }
-                    $pluginName = glob($pluginFolder.'/*.plugin*.php');
-                    if(count($pluginName)>0){
-                        $pluginName = str_replace(array($pluginFolder.'/','.enabled','.disabled','.plugin','.php'),'',$pluginName[0]);
-                        if(!file_exists($pluginBaseFolder.$pluginName)){
-                            $logger->appendLogs('Renommage...');
-                            if(rename($pluginFolder,$pluginBaseFolder.$pluginName)){
-                                $logger->appendLogs('Plugin installé, rechargez la page pour voir le plugin <span class="button notice">pensez à l\'activer</span>');
-                            }else{
-                                Functions::rmFullDir($pluginFolder);
-                                $logger->appendLogs('Impossible de renommer le plugin <span class="button error">Erreur</span>');
-                            }
-                        }else{
-                            $logger->appendLogs('Plugin déjà installé <span class="button warning">OK</span>');
-                        }
-                    }else{
-                        $logger->appendLogs('Plugin invalide, fichier principal manquant <span class="button error">Erreur</span>');
-                    }
-
-                } else {
-                    $logger->appendLogs('Echec de l\'extraction <span class="button error">Erreur</span>');
-                }
-                unlink($tempZipName);
-            }else{
-                $logger->appendLogs('Echec du téléchargement <span class="button error">Erreur</span>');
-            }
-        }
-        if(Functions::isAjaxCall()){
-            echo json_encode($logger->getLogs(), JSON_HEX_QUOT | JSON_HEX_TAG);
-        } else {
-            $logger->save();
-            header('location: ./settings.php#pluginBloc');
-        }
-    }
-
-    public function getGithubMarketRepos() {
-        header('Content-Type: application/json');
-        echo json_encode($this->getGithubMarketReposInfos($this->getGithubMarketReposList()));
-    }
-
-    protected function getGithubMarketReposList() {
-        return json_decode(self::getUrlContent("https://api.github.com/orgs/Leed-market/repos?per_page=1000"));
-    }
-
-    protected function getGithubMarketReposInfos($repos) {
-        $infos = array();
-        $installedPluginsNames = $this->getInstalledPluginsNames();
-        foreach($repos as $repo) {
-            $repoName = $repo->name;
-            if(!in_array(strtolower($repoName), $installedPluginsNames)) {
-                $infos[] = array(
-                    'name' => $repoName,
-                    'description' => isset($repo->description) ? $repo->description : false,
-                    'zipUrl' => 'https://github.com/'.$repo->full_name.'/archive/'.$repo->default_branch.'.zip'
-                );
-            }
-        }
-        return $infos;
-    }
-
-    protected function getInstalledPluginsNames() {
-        $names = array();
-        $installedPlugins = self::getAll();
-        if(!$installedPlugins || empty($installedPlugins)) {
-            return $names;
-        }
-        foreach($installedPlugins as $installedPlugin) {
-            $names[] = strtolower($installedPlugin->getName());
-        }
-        return $names;
-    }
-
-    protected static function getUrlContent($url) {
-        $timeout = 20;
-        $ch = curl_init();
-        curl_setopt($ch, CURLOPT_URL, $url);
-        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
-        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
-        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
-        curl_setopt($ch, CURLOPT_REFERER, $url);
-        curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
-        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true );
-        $datas = curl_exec($ch);
-        curl_close($ch);
-        return $datas;
-    }
-
-    public static function addHook($hookName, $functionName) {
-        $GLOBALS['hooks'][$hookName][] = $functionName;
-    }
-
-    public static function addCss($css) {
-        $bt =  debug_backtrace();
-        $pathInfo = explode('/',dirname($bt[0]['file']));
-        $count = count($pathInfo);
-        $name = $pathInfo[$count-1];
-        $path =  '.'.Plugin::FOLDER.'/'.$name.$css;
-
-        $GLOBALS['hooks']['css_files'][] = $path;
-    }
-
-    public static function callCss(){
-        $return='';
-        if(isset($GLOBALS['hooks']['css_files'])) {
-            foreach($GLOBALS['hooks']['css_files'] as $css_file) {
-                $return .='<link rel="stylesheet" href="'.$css_file.'">'."\n";
-            }
-        }
-        return $return;
-    }
-
-    public static function addLink($rel, $link, $type='', $title='') {
-        $GLOBALS['hooks']['head_link'][] = array("rel"=>$rel, "link"=>$link, "type"=>$type, "title"=>$title);
-    }
-
-    public static function callLink(){
-        $return='';
-        if(isset($GLOBALS['hooks']['head_link'])) {
-            foreach($GLOBALS['hooks']['head_link'] as $head_link) {
-                $return .='<link rel="'.$head_link['rel'].'" href="'.$head_link['link'].'" type="'.$head_link['type'].'" title="'.$head_link['title'].'" />'."\n";
-            }
-        }
-        return $return;
-    }
-
-    public static function path(){
-        $bt =  debug_backtrace();
-        $pathInfo = explode('/',dirname($bt[0]['file']));
-        $count = count($pathInfo);
-        $name = $pathInfo[$count-1];
-        return '.'.Plugin::FOLDER.'/'.$name.'/';
-    }
-
-    public static function addJs($js) {
-        $bt =  debug_backtrace();
-        $pathInfo = explode('/',dirname($bt[0]['file']));
-        $count = count($pathInfo);
-        $name = $pathInfo[$count-1];
-        $path = '.'.Plugin::FOLDER.'/'.$name.$js;
-
-        $GLOBALS['hooks']['js_files'][] = $path;
-    }
-
-    public static function callJs(){
-        $return='';
-        if(isset($GLOBALS['hooks']['js_files'])) {
-            foreach($GLOBALS['hooks']['js_files'] as $js_file) {
-                $return .='<script type="text/javascript" src="'.$js_file.'"></script>'."\n";
-            }
-        }
-        return $return;
-    }
-
-    public static function callHook($hookName, $hookArguments) {
-        //echo '<div style="display:inline;background-color:#CC47CB;padding:3px;border:5px solid #9F1A9E;border-radius:5px;color:#ffffff;font-size:15px;">'.$hookName.'</div>';
-        if(isset($GLOBALS['hooks'][$hookName])) {
-            foreach($GLOBALS['hooks'][$hookName] as $functionName) {
-                call_user_func_array($functionName, $hookArguments);
-            }
-        }
-    }
-
-    public static function getFiles($onlyActivated=false){
-
-        $enabled = $disabled =  array();
-        $files = glob(dirname(__FILE__). Plugin::FOLDER .'/*/*.plugin*.php');
-        if(empty($files))
-            $files = array();
-
-        foreach($files as $file){
-            $plugin = Plugin::getObject($file);
-            if($plugin->getState()){
-                $enabled [] =  $file;
-            }else{
-                $disabled [] =  $file;
-            }
-        }
-        if(!$onlyActivated)$enabled = array_merge($enabled,$disabled);
-        return $enabled;
-    }
-
-
-    public static function loadState($plugin){
-        $states = Plugin::getStates();
-        return (isset($states[$plugin])?$states[$plugin]:false);
-    }
-
-    public static function changeState($plugin,$state){
-        $states = Plugin::getStates();
-        $states[$plugin] = $state;
-
-        Plugin::setStates($states);
-    }
-
-
-    public static function enabled($pluginUid){
-        $plugins = Plugin::getAll();
-
-        foreach($plugins as $plugin){
-            if($plugin->getUid()==$pluginUid){
-                Plugin::changeState($plugin->getPath(),true);
-                $install = dirname($plugin->getPath()).'/install.php';
-                if(file_exists($install))require_once($install);
-            }
-        }
-    }
-    public static function disabled($pluginUid){
-        $plugins = Plugin::getAll();
-        foreach($plugins as $plugin){
-            if($plugin->getUid()==$pluginUid){
-                Plugin::changeState($plugin->getPath(),false);
-                $uninstall = dirname($plugin->getPath()).'/uninstall.php';
-                if(file_exists($uninstall))require_once($uninstall);
-            }
-        }
-
-    }
-
-    function getUid(){
-        $pathInfo = explode('/',$this->getPath());
-        $count = count($pathInfo);
-        $name = $pathInfo[$count-1];
-        return $pathInfo[$count -2].'-'.substr($name,0,strpos($name,'.'));
-    }
-
-
-    static function sortPlugin($a, $b){
-        if ($a->getState() == $b->getState())
-            if ($a->getName() == $b->getName())
-                return 0;
-            else
-                return $a->getName() < $b->getName() ? -1 : 1;
-        else
-            return $a->getState() < $b->getState() ? -1 : 1;
-    }
-
-
-
-    function getName(){
-        return $this->name;
-    }
-
-    function setName($name){
-        $this->name = $name;
-    }
-
-    function setAuthor($author){
-        $this->author = $author;
-    }
-
-    function getAuthor(){
-        return $this->author;
-    }
-
-    function getAddress(){
-        return $this->address;
-    }
-
-    function setAddress($address){
-        $this->address = $address;
-    }
-
-    function getLicence(){
-        return $this->licence;
-    }
-
-    function setLicence($licence){
-        $this->licence = $licence;
-    }
-
-    function getPath(){
-        return $this->path;
-    }
-
-    function setPath($path){
-        $this->path = $path;
-    }
-
-    function getDescription(){
-        return $this->description;
-    }
-
-    function setDescription($description){
-        $this->description = $description;
-    }
-
-
-    function getLink(){
-        return $this->link;
-    }
-
-    function setLink($link){
-        $this->link = $link;
-    }
-
-    function getVersion(){
-        return $this->version;
-    }
-
-    function setVersion($version){
-        $this->version = $version;
-    }
-
-    function getState(){
-        return $this->state;
-    }
-    function setState($state){
-        $this->state = $state;
-    }
-
-    function getType(){
-        return $this->type;
-    }
-
-    function setType($type){
-        $this->type = $type;
-    }
-
-}
-
-?>
diff --git a/leed/README.md b/leed/README.md
deleted file mode 100644
index 742fd81e621fb0e13d63e31a1cc79acc311b4a54..0000000000000000000000000000000000000000
--- a/leed/README.md
+++ /dev/null
@@ -1,210 +0,0 @@
-# Leed
-
-> Français - [English](#leed-english-documentation) - [Español](#leed-documentaci%C3%B3n-espa%C3%B1ola)
-
-Leed (contraction de Light Feed) est un agrégateur [RSS](https://fr.wikipedia.org/wiki/Rss)/[ATOM](https://fr.wikipedia.org/wiki/Atom) minimaliste qui permet la consultation de flux RSS de manière rapide et non intrusive.
-
-Cet agrégateur peut s'installer sur votre propre serveur et fonctionne avec un système de tâches [cron](https://fr.wikipedia.org/wiki/Cron) afin de traiter les informations de manière transparente et de les afficher le plus rapidement possible lorsque vous vous y connectez.
-
-- Application : Leed (Light Feed)
-- Auteur : Valentin CARRUESCO aka **Idleman** (http://blog.idleman.fr)
-- Contributeurs principaux : (par ordre alphabétique des pseudos)
-  - Maël ILLOUZ aka **Cobalt74** (https://www.cobestran.com)
-  - Christophe HENRY aka **Sbgodin** (http://sbgodin.fr)
-  - Simon ALBERNY aka **Simounet** (https://www.simounet.net)
-- Page du projet : https://github.com/LeedRSS/Leed
-- Licence : [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)
-
-Toutes les tâches de traitements de flux sont effectuées de manière invisible par une tâche programmée (cron), ainsi, l'utilisateur ne subit pas les lenteurs dues à la récupération et au traitement de chacun des flux suivis.
-
-A noter que Leed est compatible toutes résolutions, sur pc, tablette et smartphone.
-
-Leed est également compatible avec le format d'import/export [OPML](https://fr.wikipedia.org/wiki/OPML) ce qui le rend compatible avec les agrégateurs respectant ce standard.
-
-### Pré-requis
-
-- Serveur Apache conseillé (non testé sur les autres serveurs type Nginx…)
-- PHP 7.2 minimum
-- MySQL
-- Un peu de bon sens :-)
-
-### Installation
-
-1. Récupérez le projet sur la page [github](https://github.com/LeedRSS/Leed).
-2. Placez le projet dans votre répertoire web et appliquez si nécessaire une permission _chmod 775_ (si vous êtes sur un hebergement ovh, préférez un _0755_ ou vous aurez une erreur 500) sur le dossier et son contenu.
-3. Depuis votre navigateur, accédez à la page d'installation _install.php_ (ex : votre.domaine.fr/leed/install.php) et suivez les instructions.
-4. Une fois l'installation terminée, supprimez le fichier _install.php_ par mesure de sécurité.
-5. [Optionnel] Si vous souhaitez que les mises à jour de flux se fassent automatiquement, mettez en place un cron. Voir ci-après. Il est conseillé de ne pas mettre une fréquence trop rapide pour laisser le temps au script de s'exécuter.
-6. Le script est installé, merci d'avoir choisi Leed, l'agrégateur RSS svelte :p
-
-### Tâches programmées avec cron
-
-On peut éditer les tâches programmées avec _crontab -e_. Il y a deux façons de mettre à jour les flux. Les exemples qui suivent mettent à jour toutes les heures.
-
-1. En appelant directement Leed. Cette méthode a l'avantage d'être directe et de produire une sortie formatée pour la console mais requiert un accès local :
-```Batchfile
-crontab
-0 * * * * cd (...)/leed && php action.php >> logs/cron.log 2>&1
-```
-2. En appelant Leed depuis le client web _wget_. Cette méthode nécessite un accès réseau mais a l'avantage de pouvoir être déclenchée à distance. Afin de contrôler l'accès, il est nécessaire de fournir le code de synchronisation :
-```Batchfile
-0 * * * * wget --no-check-certificate --quiet --output-document /var/www/leed/cron.log
-"http://127.0.0.1/leed/action.php?action=synchronize&code=votre_code_synchronisation"
-```
- Si vous n'avez pas accès a la commande _wget_ sur votre serveur, vous pouvez essayer son chemin complet _/usr/bin/wget_.
-
-### Plugins
-
-Le dépot [Leed market](https://github.com/Leed-market) contient tous les plugins à jour et approuvés officiellement pour le logiciel Leed.
-
-### Bibliothèques utilisées
-
-- Responsive / Cross browser : Initializr (http://www.initializr.com)
-- Javascript : JQuery (http://www.jquery.com)
-- Moteur template : RainTPL (https://github.com/feulf/raintpl)
-- Parseur RSS : SimplePie (http://simplepie.org)
-- QR Code : PhpQrCode (https://sourceforge.net/projects/phpqrcode)
-- OTP : OtPhp (https://github.com/lelag/otphp)
-- Php GD : LibGD (https://libgd.github.io/)
-
-
----------
-
-
-# Leed (English documentation)
-
-Leed (short for Light Feed) is a minimalist [RSS](https://fr.wikipedia.org/wiki/Rss)/[ATOM](https://fr.wikipedia.org/wiki/Atom) aggregator which offers fast RSS consultation and non-intrusive features.
-
-This reader can be installed on your own server and works with a system of [cron](https://fr.wikipedia.org/wiki/Cron)  tasks to process information in a transparent manner and display the updates as quick as possible when you connect to it.
-
-- Application: Leed (Light Feed)
-- Author: Valentin CARRUESCO aka **Idleman** (http://blog.idleman.fr)
-- Main contributors: (alphabetical order of pseudos)
-  - Maël ILLOUZ aka **Cobalt74** (https://www.cobestran.com)
-  - Christophe HENRY aka **Sbgodin** (http://sbgodin.fr)
-  - Simon ALBERNY aka **Simounet** (https://www.simounet.net)
-- Project page: https://github.com/LeedRSS/Leed
-- License: [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)
-
-All tasks are performed in the background thanks to a scheduled task (cron), so the user does not experience delays due to the recovery and processing of each of the monitored feed.
-
-Note that Leed is compatible with all resolutions on pc, tablet and smartphone.
-
-Leed is also compatible with [OPML](https://fr.wikipedia.org/wiki/OPML) import / export which makes it compatible with aggregators applying the standard.
-
-### Prerequisites
-
-- Recommended Apache server (not tested on other webservers such as Nginx…)
-- PHP 7.2 minimum
-- MySQL
-- A little common sense :-)
-
-### Installation
-
-1. Retrieve the project archive at [github](https://github.com/LeedRSS/Leed).
-2. Place the project in your web directory and if necessary apply a permission _chmod 775_ (if you're on a ovh hosting, prefer _0755_ or you will get an error 500) onto the folder and its contents .
-3. From your browser, go to the setup page _install.php_ (eg your.domaine.fr/leed/install.ph ) and follow the instructions.
-4. Once the installation is complete, remove the _install.php_ as a security measure.
-5. [Optional] If you want the update process to run in the background, set up a crontask. See below for more info. It is advisable not to put too rapid frequency to allow time to run the script.
-6. The script is installed, thank you for choosing Leed, slender RSS aggregator :p
-
-### Scheduled tasks with cron
-
-You can edit scheduled tasks with _crontab -e_. There are two ways to update feeds. The following examples update every hour.
-
-1. Calling directly Leed. This method has the advantage of being direct and produce formatted output to the console but requires local access :
-```Batchfile
-Crontab
-0 * * * * cd (...)/leed && php action.php >> logs/cron.log 2>&1
-```
-2. Leed calling from the web client _wget_. This method requires network access but has the advantage that it can be triggered remotely. To control access, it is necessary to provide the synchronization code :
-```Batchfile
-0 * * * * wget --no-check-certificate --quiet --output-document /var/www/leed/cron.log
-"http://127.0.0.1/leed/action.php?action=synchronize&code=votre_code_synchronisation"
-```
- If you do not have access to the _wget_ command on your server, you can try the full path _/usr/bin/wget_.
-
-### Plugins
-
-The [Leed-market](https://github.com/Leed-market) repository contains all the plugins up to date and officially approved for Leed software.
-
-### Libraries used
-
-- Responsive / Cross browser: Initializr ( http://www.initializr.com )
-- Javascript: JQuery ( http://www.jquery.com )
-- Template Engine: RainTPL ( https://github.com/feulf/raintpl )
-- RSS Parser: SimplePie ( http://simplepie.org )
-- QR Code: PhpQrCode (https://sourceforge.net/projects/phpqrcode)
-- OTP: OtPhp (https://github.com/lelag/otphp)
-- Php GD : LibGD (https://libgd.github.io/)
- 
-
----------
-
-
-# Leed (Documentación española)
-
-Leed (contracción de Light Feed) es un agregator [RSS](https://fr.wikipedia.org/wiki/Rss)/[ATOM](https://fr.wikipedia.org/wiki/Atom) minimalista que permite leer sus RSS rapidamente y facilmente.
-
-Se puede instalar este agregador sobre su servidor. Leed funciona con un sistema de tareas [cron](https://fr.wikipedia.org/wiki/Cron) para procesar los RSS de manera transparente y mostrarse tan pronto como sea posible cuando se conecta.
-
-- Script : Leed (Light Feed)
-- Autor : Valentin CARRUESCO aka **Idleman** (http://blog.idleman.fr)
-- Principales contribuyentes (por orden alfabético del pseudos):
-  - Maël ILLOUZ aka **Cobalt74** (https://www.cobestran.com)
-  - Christophe HENRY aka **Sbgodin** (http://sbgodin.fr)
-  - Simon ALBERNY aka **Simounet** (https://www.simounet.net)
-- Página del proyecto : https://github.com/LeedRSS/Leed
-- Licencia : [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)
-
-Todas las tareas de tratamiento de los RSS se efectuan de manera invisible gracias a una tarea sincronizada (Cron). Así, el usuario no debe sufrir los largos tiempos necesarios para recuperar y tratar los RSS.
-
-Se debe notar que Leed es compatible con todas las resoluciones, sobre un ordenador, una tablet o un móvil y funciona con todos los navegadores.
-
-El script también está compatible con los archivos de exportación/importación [OPML](https://fr.wikipedia.org/wiki/OPML) para permitir una migración rápida y fácil a partir de todos los agregadores que respetan el formato [OPML](https://fr.wikipedia.org/wiki/OPML).
-
-### Prerrequisito
-
-- Se recomienda Apache (non testé sur les autres serveurs type Nginx…)
-- PHP versión 7.2 mínima
-- MySQL
-- Un poco de sentido común ;-)
-
-### Instalación
-
-1. Recuperar el proyecto sobre [github](https://github.com/LeedRSS/Leed).
-2. Poner el proyecto en su directorio web y aplicar un permiso _chmod 775_ sobre el directorio y su contenido (si su _web host_ es OVH, aplicar un permiso _0755_ para no tener un error 500).
-3. Desde el navegador, ir a la página de configuración _install.php_ (por ejemplo : http://su.sitio.fr/leed/install.php) y seguir las instrucciones.
-4. Una vez terminada la instalación, suprimir el archivo _install.php_ por medida de seguridad.
-5. [Opcional] Si desea que las actualizaciones sean automaticas, necesita una tarea cron. Véase más abajo. Es aconsejable no poner frecuencia demasiado rápida para que el script tenga tiempo para ejecutarse.
-6. Se ha instalado el script, gracias por elegir Leed, delgado agregador RSS: p
-
-### Tareas cron
-
-Se puede modificar las tareas cron con _crontab -e_. Hay dos maneras de actualizar los RSS. Los ejemplos siguientes actualizan los RSS cada hora.
-
-1. Llamando directamente Leed. Esta manera es directa y genera una salida formatada para el terminal, pero necesita un acceso local :
-```Batchfile
-crontab
-0 * * * * cd (...)/leed && php action.php >> logs/cron.log 2>&1
-```
-2. Llamando directamente Leed desde el cliente web _wget_. Esta manera necesita un acceso a la red pero se puede utilizarla de manera remota. Para controlar el acceso, se necesita un código de sincronización :
-```Batchfile
-0 * * * * wget --no-check-certificate --quiet --output-document /var/www/leed/cron.log
-"http://127.0.0.1/leed/action.php?action=synchronize&code=votre_code_synchronisation"
-```
- Si no tiene _wget_ en su servido, puede intentar con el camino complejo _/usr/bin/wget_.
-
-### Complementos
-
-El repositorio [Leed market](https://github.com/Leed-market) contiene todos los complementos oficialemente aprobados para Leed.
-
-### Bibliotecas usadas
-
-- Responsive / Cross browser : Initializr (http://www.initializr.com)
-- Javascript : JQuery (http://www.jquery.com)
-- PHP Template : RainTPL (https://github.com/feulf/raintpl)
-- RSS parser : SimplePie (http://simplepie.org)
-- QR Code : PhpQrCode (https://sourceforge.net/projects/phpqrcode)
-- OTP : OtPhp (https://github.com/lelag/otphp)
-- Php GD : LibGD (https://libgd.github.io/)
diff --git a/leed/RainTPL.php b/leed/RainTPL.php
deleted file mode 100644
index 941dda8894e8a26798acc285d370aede7d6eaab6..0000000000000000000000000000000000000000
--- a/leed/RainTPL.php
+++ /dev/null
@@ -1,1071 +0,0 @@
-<?php
-
-/**
- *  RainTPL
- *  -------
- *  Realized by Federico Ulfo & maintained by the Rain Team
- *  Distributed under GNU/LGPL 3 License
- *
- *  @version 2.7.2
- */
-
-
-class RainTPL{
-
-	// -------------------------
-	// 	CONFIGURATION
-	// -------------------------
-
-		/**
-		 * Template directory
-		 *
-		 * @var string
-		 */
-		static $tpl_dir = "tpl/";
-
-
-		/**
-		 * Cache directory. Is the directory where RainTPL will compile the template and save the cache
-		 *
-		 * @var string
-		 */
-		static $cache_dir = "tmp/";
-
-
-		/**
-		 * Template base URL. RainTPL will add this URL to the relative paths of element selected in $path_replace_list.
-		 *
-		 * @var string
-		 */
-		static $base_url = null;
-
-
-		/**
-		 * Template extension.
-		 *
-		 * @var string
-		 */
-		static $tpl_ext = "html";
-
-
-		/**
-		 * Path replace is a cool features that replace all relative paths of images (<img src="...">), stylesheet (<link href="...">), script (<script src="...">) and link (<a href="...">)
-		 * Set true to enable the path replace.
-		 *
-		 * @var unknown_type
-		 */
-		static $path_replace = true;
-
-
-		/**
-		 * You can set what the path_replace method will replace.
-		 * Avaible options: a, img, link, script, input
-		 *
-		 * @var array
-		 */
-		static $path_replace_list = array( 'a', 'img', 'link', 'script', 'input' );
-
-
-		/**
-		 * You can define in the black list what string are disabled into the template tags
-		 *
-		 * @var unknown_type
-		 */
-		static $black_list = array( '\$this', 'raintpl::', 'self::', '_SESSION', '_SERVER', '_ENV',  'eval', 'exec', 'unlink', 'rmdir' );
-
-
-		/**
-		 * Check template.
-		 * true: checks template update time, if changed it compile them
-		 * false: loads the compiled template. Set false if server doesn't have write permission for cache_directory.
-		 *
-		 */
-		static $check_template_update = true;
-
-
-		/**
-		 * PHP tags <? ?>
-		 * True: php tags are enabled into the template
-		 * False: php tags are disabled into the template and rendered as html
-		 *
-		 * @var bool
-		 */
-		static $php_enabled = false;
-
-
-		/**
-		 * Debug mode flag.
-		 * True: debug mode is used, syntax errors are displayed directly in template. Execution of script is not terminated.
-		 * False: exception is thrown on found error.
-		 *
-		 * @var bool
-		 */
-		static $debug = false;
-
-	// -------------------------
-
-
-	// -------------------------
-	// 	RAINTPL VARIABLES
-	// -------------------------
-
-		/**
-		 * Is the array where RainTPL keep the variables assigned
-		 *
-		 * @var array
-		 */
-		public $var = array();
-
-		protected $tpl = array(),		// variables to keep the template directories and info
-				  $cache = false,		// static cache enabled / disabled
-                  $cache_id = null;       // identify only one cache
-
-                protected static $config_name_sum = array();   // takes all the config to create the md5 of the file
-
-	// -------------------------
-
-
-
-	const CACHE_EXPIRE_TIME = 3600; // default cache expire time = hour
-
-
-
-	/**
-	 * Assign variable
-	 * eg. 	$t->assign('name','mickey');
-	 *
-	 * @param mixed $variable_name Name of template variable or associative array name/value
-	 * @param mixed $value value assigned to this variable. Not set if variable_name is an associative array
-	 */
-
-	function assign( $variable, $value = null ){
-		if( is_array( $variable ) )
-			$this->var = $variable + $this->var;
-		else
-			$this->var[ $variable ] = $value;
-	}
-
-
-
-	/**
-	 * Draw the template
-	 * eg. 	$html = $tpl->draw( 'demo', TRUE ); // return template in string
-	 * or 	$tpl->draw( $tpl_name ); // echo the template
-	 *
-	 * @param string $tpl_name  template to load
-	 * @param boolean $return_string  true=return a string, false=echo the template
-	 * @return string
-	 */
-
-	function draw( $tpl_name, $return_string = false ){
-
-		try {
-			// compile the template if necessary and set the template filepath
-			$this->check_template( $tpl_name );
-		} catch (RainTpl_Exception $e) {
-			$output = $this->printDebug($e);
-			die($output);
-		}
-
-		// Cache is off and, return_string is false
-        // Rain just echo the template
-
-        if( !$this->cache && !$return_string ){
-            extract( $this->var );
-            include $this->tpl['compiled_filename'];
-            unset( $this->tpl );
-        }
-
-
-		// cache or return_string are enabled
-        // rain get the output buffer to save the output in the cache or to return it as string
-
-        else{
-
-            //----------------------
-            // get the output buffer
-            //----------------------
-                ob_start();
-                extract( $this->var );
-                include $this->tpl['compiled_filename'];
-                $raintpl_contents = ob_get_clean();
-            //----------------------
-
-
-            // save the output in the cache
-            if( $this->cache )
-                file_put_contents( $this->tpl['cache_filename'], "<?php if(!class_exists('raintpl')){exit;}?>" . $raintpl_contents );
-
-            // free memory
-            unset( $this->tpl );
-
-            // return or print the template
-            if( $return_string ) return $raintpl_contents; else echo $raintpl_contents;
-
-        }
-
-	}
-
-
-
-	/**
-	 * If exists a valid cache for this template it returns the cache
-	 *
-	 * @param string $tpl_name Name of template (set the same of draw)
-	 * @param int $expiration_time Set after how many seconds the cache expire and must be regenerated
-	 * @return string it return the HTML or null if the cache must be recreated
-	 */
-
-	function cache( $tpl_name, $expire_time = self::CACHE_EXPIRE_TIME, $cache_id = null ){
-
-        // set the cache_id
-        $this->cache_id = $cache_id;
-
-		if( !$this->check_template( $tpl_name ) && file_exists( $this->tpl['cache_filename'] ) && ( time() - filemtime( $this->tpl['cache_filename'] ) < $expire_time ) ){
-			// return the cached file as HTML. It remove the first 43 character, which are a PHP code to secure the file <?php if(!class_exists('raintpl')){exit;}? >
-			return substr( file_get_contents( $this->tpl['cache_filename'] ), 43 );
-		}
-		else{
-			//delete the cache of the selected template
-            if (file_exists($this->tpl['cache_filename']))
-            unlink($this->tpl['cache_filename'] );
-			$this->cache = true;
-		}
-	}
-
-
-
-	/**
-	 * Configure the settings of RainTPL
-	 *
-	 */
-	static function configure( $setting, $value = null ){
-		if( is_array( $setting ) )
-			foreach( $setting as $key => $value )
-				self::configure( $key, $value );
-		else if( property_exists( __CLASS__, $setting ) ){
-			self::$$setting = $value;
-            self::$config_name_sum[ $setting ] = $value; // take trace of all config
-        }
-	}
-
-
-
-	// check if has to compile the template
-	// return true if the template has changed
-	protected function check_template( $tpl_name ){
-
-		if( !isset($this->tpl['checked']) ){
-
-			$tpl_basename                       = basename( $tpl_name );														// template basename
-			$tpl_basedir                        = strpos($tpl_name,"/") ? dirname($tpl_name) . '/' : null;						// template basedirectory
-			$this->tpl['template_directory']    = self::$tpl_dir . $tpl_basedir;								// template directory
-			$this->tpl['tpl_filename']          = $this->tpl['template_directory'] . $tpl_basename . '.' . self::$tpl_ext;	// template filename
-			$temp_compiled_filename             = self::$cache_dir . $tpl_basename . "." . md5( $this->tpl['template_directory'] . serialize(self::$config_name_sum));
-			$this->tpl['compiled_filename']     = $temp_compiled_filename . '.rtpl.php';	// cache filename
-			$this->tpl['cache_filename']        = $temp_compiled_filename . '.s_' . $this->cache_id . '.rtpl.php';	// static cache filename
-                        $this->tpl['checked']               = true;
-
-			// if the template doesn't exist and is not an external source throw an error
-			if( self::$check_template_update && !file_exists( $this->tpl['tpl_filename'] ) && !preg_match('/http/', $tpl_name) ){
-				$e = new RainTpl_NotFoundException( 'Template '. $tpl_basename .' not found!' );
-				throw $e->setTemplateFile($this->tpl['tpl_filename']);
-			}
-
-			// We check if the template is not an external source
-			if(preg_match('/http/', $tpl_name)){
-				$this->compileFile('', '', $tpl_name, self::$cache_dir, $this->tpl['compiled_filename'] );
-				return true;
-			}
-			// file doesn't exist, or the template was updated, Rain will compile the template
-			elseif( !file_exists( $this->tpl['compiled_filename'] ) || ( self::$check_template_update && filemtime($this->tpl['compiled_filename']) < filemtime( $this->tpl['tpl_filename'] ) ) ){
-				$this->compileFile( $tpl_basename, $tpl_basedir, $this->tpl['tpl_filename'], self::$cache_dir, $this->tpl['compiled_filename'] );
-				return true;
-			}
-
-		}
-	}
-
-
-	/**
-	* execute stripslaches() on the xml block. Invoqued by preg_replace_callback function below
-	* @access protected
-	*/
-	protected function xml_reSubstitution($capture) {
-    		return "<?php echo '<?xml ".stripslashes($capture[1])." ?>'; ?>";
-	}
-
-	/**
-	 * Compile and write the compiled template file
-	 * @access protected
-	 */
-	protected function compileFile( $tpl_basename, $tpl_basedir, $tpl_filename, $cache_dir, $compiled_filename ){
-
-		//read template file
-		$this->tpl['source'] = $template_code = file_get_contents( $tpl_filename );
-
-		//xml substitution
-		$template_code = preg_replace( "/<\?xml(.*?)\?>/s", "##XML\\1XML##", $template_code );
-
-		//disable php tag
-		if( !self::$php_enabled )
-			$template_code = str_replace( array("<?","?>"), array("&lt;?","?&gt;"), $template_code );
-
-		//xml re-substitution
-		$template_code = preg_replace_callback ( "/##XML(.*?)XML##/s", array($this, 'xml_reSubstitution'), $template_code );
-
-		//compile template
-		$template_compiled = "<?php if(!class_exists('raintpl')){exit;}?>" . $this->compileTemplate( $template_code, $tpl_basedir );
-
-
-		// fix the php-eating-newline-after-closing-tag-problem
-		$template_compiled = str_replace( "?>\n", "?>\n\n", $template_compiled );
-
-		// create directories
-		if( !is_dir( $cache_dir ) )
-			mkdir( $cache_dir, 0755, true );
-
-		if( !is_writable( $cache_dir ) )
-			throw new RainTpl_Exception ('Cache directory ' . $cache_dir . 'doesn\'t have write permission. Set write permission or set RAINTPL_CHECK_TEMPLATE_UPDATE to false. More details on https://github.com/feulf/raintpl');
-
-		//write compiled file
-		file_put_contents( $compiled_filename, $template_compiled );
-	}
-
-
-
-	/**
-	 * Compile template
-	 * @access protected
-	 */
-	protected function compileTemplate( $template_code, $tpl_basedir ){
-
-		//tag list
-		$tag_regexp = array( 'loop'         => '(\{loop(?: name){0,1}="\${0,1}[^"]*"\})',
-                             'loop_close'   => '(\{\/loop\})',
-                             'if'           => '(\{if(?: condition){0,1}="[^"]*"\})',
-                             'elseif'       => '(\{elseif(?: condition){0,1}="[^"]*"\})',
-                             'else'         => '(\{else\})',
-                             'if_close'     => '(\{\/if\})',
-                             'function'     => '(\{function="[^"]*"\})',
-                             'noparse'      => '(\{noparse\})',
-                             'noparse_close'=> '(\{\/noparse\})',
-                             'ignore'       => '(\{ignore\}|\{\*)',
-                             'ignore_close'	=> '(\{\/ignore\}|\*\})',
-                             'include'      => '(\{include="[^"]*"(?: cache="[^"]*")?\})',
-                             'template_info'=> '(\{\$template_info\})',
-                             'function'		=> '(\{function="(\w*?)(?:.*?)"\})'
-							);
-
-		$tag_regexp = "/" . join( "|", $tag_regexp ) . "/";
-
-		//split the code with the tags regexp
-		$template_code = preg_split ( $tag_regexp, $template_code, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
-
-		//path replace (src of img, background and href of link)
-		$template_code = $this->path_replace( $template_code, $tpl_basedir );
-
-		//compile the code
-		$compiled_code = $this->compileCode( $template_code );
-
-		//return the compiled code
-		return $compiled_code;
-
-	}
-
-
-
-	/**
-	 * Compile the code
-	 * @access protected
-	 */
-	protected function compileCode( $parsed_code ){
-
-                // if parsed code is empty return null string
-                if( !$parsed_code )
-                    return "";
-
-		//variables initialization
-		$compiled_code = $open_if = $comment_is_open = $ignore_is_open = null;
-                $loop_level = 0;
-
-
-	 	//read all parsed code
-	 	foreach( $parsed_code as $html ){
-
-	 		//close ignore tag
-			if( !$comment_is_open && ( strpos( $html, '{/ignore}' ) !== FALSE || strpos( $html, '*}' ) !== FALSE ) )
-	 			$ignore_is_open = false;
-
-	 		//code between tag ignore id deleted
-	 		elseif( $ignore_is_open ){
-	 			//ignore the code
-	 		}
-
-	 		//close no parse tag
-			elseif( strpos( $html, '{/noparse}' ) !== FALSE )
-	 			$comment_is_open = false;
-
-	 		//code between tag noparse is not compiled
-	 		elseif( $comment_is_open )
- 				$compiled_code .= $html;
-
-	 		//ignore
-			elseif( strpos( $html, '{ignore}' ) !== FALSE || strpos( $html, '{*' ) !== FALSE )
-	 			$ignore_is_open = true;
-
-	 		//noparse
-	 		elseif( strpos( $html, '{noparse}' ) !== FALSE )
-	 			$comment_is_open = true;
-
-			//include tag
-			elseif( preg_match( '/\{include="([^"]*)"(?: cache="([^"]*)"){0,1}\}/', $html, $code ) ){
-				if (preg_match("/http/", $code[1])) {
-					$content = file_get_contents($code[1]);
-					$compiled_code .= $content;
-				} else {
-					//variables substitution
-					$include_var = $this->var_replace( $code[ 1 ], $left_delimiter = null, $right_delimiter = null, $php_left_delimiter = '".' , $php_right_delimiter = '."', $loop_level );
-
-                                        //get the folder of the actual template
-                                        $actual_folder = substr( $this->tpl['template_directory'], strlen(self::$tpl_dir) );
-
-                                        //get the included template
-                                        $include_template = $actual_folder . $include_var;
-
-                                        // reduce the path
-                                        $include_template = $this->reduce_path( $include_template );
-
-					// if the cache is active
-					if( isset($code[ 2 ]) ){
-
-                                                //include
-                                                $compiled_code .= '<?php $tpl = new '.get_called_class().';' .
-                                                                  'if( $cache = $tpl->cache( "'.$include_template.'" ) )' .
-								  '	echo $cache;' .
-								  'else{' .
-                                                                  '$tpl->assign( $this->var );' .
-                                                                  ( !$loop_level ? null : '$tpl->assign( "key", $key'.$loop_level.' ); $tpl->assign( "value", $value'.$loop_level.' );' ).
-                                                                  '$tpl->draw( "'.$include_template.'" );'.
-                                                                  '}' .
-                                                                  '?>';
-
-					}
-					else{
-                                                //include
-                                                $compiled_code .= '<?php $tpl = new '.get_called_class().';' .
-                                                                  '$tpl->assign( $this->var );' .
-                                                                  ( !$loop_level ? null : '$tpl->assign( "key", $key'.$loop_level.' ); $tpl->assign( "value", $value'.$loop_level.' );' ).
-                                                                  '$tpl->draw( "'.$include_template.'" );'.
-                                                                  '?>';
-
-					}
-				}
-			}
-
-	 		//loop
-			elseif( preg_match( '/\{loop(?: name){0,1}="\${0,1}([^"]*)"\}/', $html, $code ) ){
-
-	 			//increase the loop counter
-	 			$loop_level++;
-
-				//replace the variable in the loop
-				$var = $this->var_replace( '$' . $code[ 1 ], $tag_left_delimiter=null, $tag_right_delimiter=null, $php_left_delimiter=null, $php_right_delimiter=null, $loop_level-1 );
-
-				//loop variables
-				$counter = "\$counter$loop_level";       // count iteration
-				$key = "\$key$loop_level";               // key
-				$value = "\$value$loop_level";           // value
-
-				//loop code
-				$compiled_code .=  "<?php $counter=-1; if( isset($var) && is_array($var) && sizeof($var) ) foreach( $var as $key => $value ){ $counter++; ?>";
-
-			}
-
-			//close loop tag
-			elseif( strpos( $html, '{/loop}' ) !== FALSE ) {
-
-				//iterator
-				$counter = "\$counter$loop_level";
-
-				//decrease the loop counter
-				$loop_level--;
-
-				//close loop code
-				$compiled_code .=  "<?php } ?>";
-
-			}
-
-			//if
-			elseif( preg_match( '/\{if(?: condition){0,1}="([^"]*)"\}/', $html, $code ) ){
-
-				//increase open if counter (for intendation)
-				$open_if++;
-
-				//tag
-				$tag = $code[ 0 ];
-
-				//condition attribute
-				$condition = $code[ 1 ];
-
-				// check if there's any function disabled by black_list
-				$this->function_check( $tag );
-
-				//variable substitution into condition (no delimiter into the condition)
-				$parsed_condition = $this->var_replace( $condition, $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level );
-
-				//if code
-				$compiled_code .=   "<?php if( $parsed_condition ){ ?>";
-
-			}
-
-			//elseif
-			elseif( preg_match( '/\{elseif(?: condition){0,1}="([^"]*)"\}/', $html, $code ) ){
-
-				//tag
-				$tag = $code[ 0 ];
-
-				//condition attribute
-				$condition = $code[ 1 ];
-
-				//variable substitution into condition (no delimiter into the condition)
-				$parsed_condition = $this->var_replace( $condition, $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level );
-
-				//elseif code
-				$compiled_code .=   "<?php }elseif( $parsed_condition ){ ?>";
-			}
-
-			//else
-			elseif( strpos( $html, '{else}' ) !== FALSE ) {
-
-				//else code
-				$compiled_code .=   '<?php }else{ ?>';
-
-			}
-
-			//close if tag
-			elseif( strpos( $html, '{/if}' ) !== FALSE ) {
-
-				//decrease if counter
-				$open_if--;
-
-				// close if code
-				$compiled_code .=   '<?php } ?>';
-
-			}
-
-			//function
-			elseif( preg_match( '/\{function="(\w*)(.*?)"\}/', $html, $code ) ){
-
-				//tag
-				$tag = $code[ 0 ];
-
-				//function
-				$function = $code[ 1 ];
-
-				// check if there's any function disabled by black_list
-				$this->function_check( $tag );
-
-				if( empty( $code[ 2 ] ) )
-					$parsed_function = $function . "()";
-				else
-					// parse the function
-					$parsed_function = $function . $this->var_replace( $code[ 2 ], $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level );
-
-				//if code
-				$compiled_code .=   "<?php echo $parsed_function; ?>";
-			}
-
-			// show all vars
-			elseif ( strpos( $html, '{$template_info}' ) !== FALSE ) {
-
-				//tag
-				$tag  = '{$template_info}';
-
-				//if code
-				$compiled_code .=   '<?php echo "<pre>"; print_r( $this->var ); echo "</pre>"; ?>';
-			}
-
-
-			//all html code
-			else{
-
-				//variables substitution (es. {$title})
-				$html = $this->var_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '<?php ', $php_right_delimiter = ';?>', $loop_level, $echo = true );
-				//const substitution (es. {#CONST#})
-				$html = $this->const_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '<?php ', $php_right_delimiter = ';?>', $loop_level, $echo = true );
-				//functions substitution (es. {"string"|functions})
-				$compiled_code .= $this->func_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '<?php ', $php_right_delimiter = ';?>', $loop_level, $echo = true );
-			}
-		}
-
-		if( $open_if > 0 ) {
-			$e = new RainTpl_SyntaxException('Error! You need to close an {if} tag in ' . $this->tpl['tpl_filename'] . ' template');
-			throw $e->setTemplateFile($this->tpl['tpl_filename']);
-		}
-		return $compiled_code;
-	}
-
-
-	/**
-	 * Reduce a path, eg. www/library/../filepath//file => www/filepath/file
-	 * @param type $path
-	 * @return type
-	 */
-	protected function reduce_path( $path ){
-            $path = str_replace( "://", "@not_replace@", $path );
-            $path = preg_replace( "#(/+)#", "/", $path );
-            $path = preg_replace( "#(/\./+)#", "/", $path );
-            $path = str_replace( "@not_replace@", "://", $path );
-
-            while( preg_match( '#\.\./#', $path ) ){
-                $path = preg_replace('#\w+/\.\./#', '', $path );
-            }
-            return $path;
-	}
-
-
-
-	/**
-	 * replace the path of image src, link href and a href.
-	 * url => template_dir/url
-	 * url# => url
-	 * http://url => http://url
-	 *
-	 * @param string $html
-	 * @return string html sostituito
-	 */
-	protected function path_replace( $html, $tpl_basedir ){
-
-		if( self::$path_replace ){
-
-			$tpl_dir = self::$base_url . self::$tpl_dir . $tpl_basedir;
-
-			// reduce the path
-			$path = $this->reduce_path($tpl_dir);
-
-			$exp = $sub = array();
-
-			if( in_array( "img", self::$path_replace_list ) ){
-				$exp = array( '/<img(.*?)src=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<img(.*?)src=(?:")([^"]+?)#(?:")/i', '/<img(.*?)src="(.*?)"/', '/<img(.*?)src=(?:\@)([^"]+?)(?:\@)/i' );
-				$sub = array( '<img$1src=@$2://$3@', '<img$1src=@$2@', '<img$1src="' . $path . '$2"', '<img$1src="$2"' );
-			}
-
-			if( in_array( "script", self::$path_replace_list ) ){
-				$exp = array_merge( $exp , array( '/<script(.*?)src=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<script(.*?)src=(?:")([^"]+?)#(?:")/i', '/<script(.*?)src="(.*?)"/', '/<script(.*?)src=(?:\@)([^"]+?)(?:\@)/i' ) );
-				$sub = array_merge( $sub , array( '<script$1src=@$2://$3@', '<script$1src=@$2@', '<script$1src="' . $path . '$2"', '<script$1src="$2"' ) );
-			}
-
-			if( in_array( "link", self::$path_replace_list ) ){
-				$exp = array_merge( $exp , array( '/<link(.*?)href=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<link(.*?)href=(?:")([^"]+?)#(?:")/i', '/<link(.*?)href="(.*?)"/', '/<link(.*?)href=(?:\@)([^"]+?)(?:\@)/i' ) );
-				$sub = array_merge( $sub , array( '<link$1href=@$2://$3@', '<link$1href=@$2@' , '<link$1href="' . $path . '$2"', '<link$1href="$2"' ) );
-			}
-
-			if( in_array( "a", self::$path_replace_list ) ){
-				$exp = array_merge( $exp , array( '/<a(.*?)href=(?:")(http\:\/\/|https\:\/\/|javascript:|mailto:)([^"]+?)(?:")/i', '/<a(.*?)href="(.*?)"/', '/<a(.*?)href=(?:\@)([^"]+?)(?:\@)/i'  ) );
-				$sub = array_merge( $sub , array( '<a$1href="$2$3"', '<a$1href="' . self::$base_url . '$2"', '<a$1href="$2"' ) );
-			}
-
-			if( in_array( "input", self::$path_replace_list ) ){
-				$exp = array_merge( $exp , array( '/<input(.*?)src=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<input(.*?)src=(?:")([^"]+?)#(?:")/i', '/<input(.*?)src="(.*?)"/', '/<input(.*?)src=(?:\@)([^"]+?)(?:\@)/i' ) );
-				$sub = array_merge( $sub , array( '<input$1src=@$2://$3@', '<input$1src=@$2@', '<input$1src="' . $path . '$2"', '<input$1src="$2"' ) );
-			}
-
-			return preg_replace( $exp, $sub, $html );
-
-		}
-		else
-			return $html;
-
-	}
-
-
-
-
-
-	// replace const
-	function const_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){
-		// const
-		return preg_replace( '/\{\#(\w+)\#{0,1}\}/', $php_left_delimiter . ( $echo ? " echo " : null ) . '\\1' . $php_right_delimiter, $html );
-	}
-
-
-
-	// replace functions/modifiers on constants and strings
-	function func_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){
-
-		preg_match_all( '/' . '\{\#{0,1}(\"{0,1}.*?\"{0,1})(\|\w.*?)\#{0,1}\}' . '/', $html, $matches );
-
-		for( $i=0, $n=count($matches[0]); $i<$n; $i++ ){
-
-			//complete tag ex: {$news.title|substr:0,100}
-			$tag = $matches[ 0 ][ $i ];
-
-			//variable name ex: news.title
-			$var = $matches[ 1 ][ $i ];
-
-			//function and parameters associate to the variable ex: substr:0,100
-			$extra_var = $matches[ 2 ][ $i ];
-
-			// check if there's any function disabled by black_list
-			$this->function_check( $tag );
-
-			$extra_var = $this->var_replace( $extra_var, null, null, null, null, $loop_level );
-
-
-			// check if there's an operator = in the variable tags, if there's this is an initialization so it will not output any value
-			$is_init_variable = preg_match( "/^(\s*?)\=[^=](.*?)$/", $extra_var );
-
-			//function associate to variable
-			$function_var = ( $extra_var and $extra_var[0] == '|') ? substr( $extra_var, 1 ) : null;
-
-			//variable path split array (ex. $news.title o $news[title]) or object (ex. $news->title)
-			$temp = preg_split( "/\.|\[|\-\>/", $var );
-
-			//variable name
-			$var_name = $temp[ 0 ];
-
-			//variable path
-			$variable_path = substr( $var, strlen( $var_name ) );
-
-			//parentesis transform [ e ] in [" e in "]
-			$variable_path = str_replace( '[', '["', $variable_path );
-			$variable_path = str_replace( ']', '"]', $variable_path );
-
-			//transform .$variable in ["$variable"]
-			$variable_path = preg_replace('/\.\$(\w+)/', '["$\\1"]', $variable_path );
-
-			//transform [variable] in ["variable"]
-			$variable_path = preg_replace('/\.(\w+)/', '["\\1"]', $variable_path );
-
-			//if there's a function
-			if( $function_var ){
-
-                // check if there's a function or a static method and separate, function by parameters
-				$function_var = str_replace("::", "@double_dot@", $function_var );
-
-                // get the position of the first :
-                if( $dot_position = strpos( $function_var, ":" ) ){
-
-                    // get the function and the parameters
-                    $function = substr( $function_var, 0, $dot_position );
-                    $params = substr( $function_var, $dot_position+1 );
-
-                }
-                else{
-
-                    //get the function
-                    $function = str_replace( "@double_dot@", "::", $function_var );
-                    $params = null;
-
-                }
-
-                // replace back the @double_dot@ with ::
-                $function = str_replace( "@double_dot@", "::", $function );
-                $params = str_replace( "@double_dot@", "::", $params );
-
-
-			}
-			else
-				$function = $params = null;
-
-			$php_var = $var_name . $variable_path;
-
-			// compile the variable for php
-			if( isset( $function ) ){
-				if( $php_var )
-					$php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $php_var, $params ) )" : "$function( $php_var )" ) . $php_right_delimiter;
-				else
-					$php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $params ) )" : "$function()" ) . $php_right_delimiter;
-			}
-			else
-				$php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . $php_var . $extra_var . $php_right_delimiter;
-
-			$html = str_replace( $tag, $php_var, $html );
-
-		}
-
-		return $html;
-
-	}
-
-
-
-	function var_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){
-
-		//all variables
-		if( preg_match_all( '/' . $tag_left_delimiter . '\$(\w+(?:\.\${0,1}[A-Za-z0-9_]+)*(?:(?:\[\${0,1}[A-Za-z0-9_]+\])|(?:\-\>\${0,1}[A-Za-z0-9_]+))*)(.*?)' . $tag_right_delimiter . '/', $html, $matches ) ){
-
-                    for( $parsed=array(), $i=0, $n=count($matches[0]); $i<$n; $i++ )
-                        $parsed[$matches[0][$i]] = array('var'=>$matches[1][$i],'extra_var'=>$matches[2][$i]);
-
-                    foreach( $parsed as $tag => $array ){
-
-                            //variable name ex: news.title
-                            $var = $array['var'];
-
-                            //function and parameters associate to the variable ex: substr:0,100
-                            $extra_var = $array['extra_var'];
-
-                            // check if there's any function disabled by black_list
-                            $this->function_check( $tag );
-
-                            $extra_var = $this->var_replace( $extra_var, null, null, null, null, $loop_level );
-
-                            // check if there's an operator = in the variable tags, if there's this is an initialization so it will not output any value
-                            $is_init_variable = preg_match( "/^[a-z_A-Z\.\[\](\-\>)]*=[^=]*$/", $extra_var );
-
-                            //function associate to variable
-                            $function_var = ( $extra_var and $extra_var[0] == '|') ? substr( $extra_var, 1 ) : null;
-
-                            //variable path split array (ex. $news.title o $news[title]) or object (ex. $news->title)
-                            $temp = preg_split( "/\.|\[|\-\>/", $var );
-
-                            //variable name
-                            $var_name = $temp[ 0 ];
-
-                            //variable path
-                            $variable_path = substr( $var, strlen( $var_name ) );
-
-                            //parentesis transform [ e ] in [" e in "]
-                            $variable_path = str_replace( '[', '["', $variable_path );
-                            $variable_path = str_replace( ']', '"]', $variable_path );
-
-                            //transform .$variable in ["$variable"] and .variable in ["variable"]
-                            $variable_path = preg_replace('/\.(\${0,1}\w+)/', '["\\1"]', $variable_path );
-
-                            // if is an assignment also assign the variable to $this->var['value']
-                            if( $is_init_variable )
-                                $extra_var = "=\$this->var['{$var_name}']{$variable_path}" . $extra_var;
-
-
-
-                            //if there's a function
-                            if( $function_var ){
-
-                                    // check if there's a function or a static method and separate, function by parameters
-                                    $function_var = str_replace("::", "@double_dot@", $function_var );
-
-
-                                    // get the position of the first :
-                                    if( $dot_position = strpos( $function_var, ":" ) ){
-
-                                        // get the function and the parameters
-                                        $function = substr( $function_var, 0, $dot_position );
-                                        $params = substr( $function_var, $dot_position+1 );
-
-                                    }
-                                    else{
-
-                                        //get the function
-                                        $function = str_replace( "@double_dot@", "::", $function_var );
-                                        $params = null;
-
-                                    }
-
-                                    // replace back the @double_dot@ with ::
-                                    $function = str_replace( "@double_dot@", "::", $function );
-                                    $params = str_replace( "@double_dot@", "::", $params );
-                            }
-                            else
-                                    $function = $params = null;
-
-                            //if it is inside a loop
-                            if( $loop_level ){
-                                    //verify the variable name
-                                    if( $var_name == 'key' )
-                                            $php_var = '$key' . $loop_level;
-                                    elseif( $var_name == 'value' )
-                                            $php_var = '$value' . $loop_level . $variable_path;
-                                    elseif( $var_name == 'counter' )
-                                            $php_var = '$counter' . $loop_level;
-                                    else
-                                            $php_var = '$' . $var_name . $variable_path;
-                            }else
-                                    $php_var = '$' . $var_name . $variable_path;
-
-                            // compile the variable for php
-                            if( isset( $function ) )
-                                    $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $php_var, $params ) )" : "$function( $php_var )" ) . $php_right_delimiter;
-                            else
-                                    $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . $php_var . $extra_var . $php_right_delimiter;
-
-                            $html = str_replace( $tag, $php_var, $html );
-
-
-                    }
-                }
-
-		return $html;
-	}
-
-
-
-	/**
-	 * Check if function is in black list (sandbox)
-	 *
-	 * @param string $code
-	 * @param string $tag
-	 */
-	protected function function_check( $code ){
-
-		$preg = '#(\W|\s)' . implode( '(\W|\s)|(\W|\s)', self::$black_list ) . '(\W|\s)#';
-
-		// check if the function is in the black list (or not in white list)
-		if( count(self::$black_list) && preg_match( $preg, $code, $match ) ){
-
-			// find the line of the error
-			$line = 0;
-			$rows=explode("\n",$this->tpl['source']);
-			while( !strpos($rows[$line],$code) )
-				$line++;
-
-			// stop the execution of the script
-			$e = new RainTpl_SyntaxException('Unallowed syntax in ' . $this->tpl['tpl_filename'] . ' template');
-			throw $e->setTemplateFile($this->tpl['tpl_filename'])
-				->setTag($code)
-				->setTemplateLine($line);
-		}
-
-	}
-
-	/**
-	 * Prints debug info about exception or passes it further if debug is disabled.
-	 *
-	 * @param RainTpl_Exception $e
-	 * @return string
-	 */
-	protected function printDebug(RainTpl_Exception $e){
-		if (!self::$debug) {
-			throw $e;
-		}
-		$output = sprintf('<h2>Exception: %s</h2><h3>%s</h3><p>template: %s</p>',
-			get_class($e),
-			$e->getMessage(),
-			$e->getTemplateFile()
-		);
-		if ($e instanceof RainTpl_SyntaxException) {
-			if (null != $e->getTemplateLine()) {
-				$output .= '<p>line: ' . $e->getTemplateLine() . '</p>';
-			}
-			if (null != $e->getTag()) {
-				$output .= '<p>in tag: ' . htmlspecialchars($e->getTag()) . '</p>';
-			}
-			if (null != $e->getTemplateLine() && null != $e->getTag()) {
-				$rows=explode("\n",  htmlspecialchars($this->tpl['source']));
-				$rows[$e->getTemplateLine()] = '<font color=red>' . $rows[$e->getTemplateLine()] . '</font>';
-				$output .= '<h3>template code</h3>' . implode('<br />', $rows) . '</pre>';
-			}
-		}
-		$output .= sprintf('<h3>trace</h3><p>In %s on line %d</p><pre>%s</pre>',
-			$e->getFile(), $e->getLine(),
-			nl2br(htmlspecialchars($e->getTraceAsString()))
-		);
-		return $output;
-	}
-}
-
-
-/**
- * Basic Rain tpl exception.
- */
-class RainTpl_Exception extends Exception{
-	/**
-	 * Path of template file with error.
-	 */
-	protected $templateFile = '';
-
-	/**
-	 * Returns path of template file with error.
-	 *
-	 * @return string
-	 */
-	public function getTemplateFile()
-	{
-		return $this->templateFile;
-	}
-
-	/**
-	 * Sets path of template file with error.
-	 *
-	 * @param string $templateFile
-	 * @return RainTpl_Exception
-	 */
-	public function setTemplateFile($templateFile)
-	{
-		$this->templateFile = (string) $templateFile;
-		return $this;
-	}
-}
-
-/**
- * Exception thrown when template file does not exists.
- */
-class RainTpl_NotFoundException extends RainTpl_Exception{
-}
-
-/**
- * Exception thrown when syntax error occurs.
- */
-class RainTpl_SyntaxException extends RainTpl_Exception{
-	/**
-	 * Line in template file where error has occured.
-	 *
-	 * @var int | null
-	 */
-	protected $templateLine = null;
-
-	/**
-	 * Tag which caused an error.
-	 *
-	 * @var string | null
-	 */
-	protected $tag = null;
-
-	/**
-	 * Returns line in template file where error has occured
-	 * or null if line is not defined.
-	 *
-	 * @return int | null
-	 */
-	public function getTemplateLine()
-	{
-		return $this->templateLine;
-	}
-
-	/**
-	 * Sets  line in template file where error has occured.
-	 *
-	 * @param int $templateLine
-	 * @return RainTpl_SyntaxException
-	 */
-	public function setTemplateLine($templateLine)
-	{
-		$this->templateLine = (int) $templateLine;
-		return $this;
-	}
-
-	/**
-	 * Returns tag which caused an error.
-	 *
-	 * @return string
-	 */
-	public function getTag()
-	{
-		return $this->tag;
-	}
-
-	/**
-	 * Sets tag which caused an error.
-	 *
-	 * @param string $tag
-	 * @return RainTpl_SyntaxException
-	 */
-	public function setTag($tag)
-	{
-		$this->tag = (string) $tag;
-		return $this;
-	}
-}
-
-// -- end
diff --git a/leed/SimplePie.class.php b/leed/SimplePie.class.php
deleted file mode 100644
index a027e82fac521f39d6f8aac109fc37f8741e0fd0..0000000000000000000000000000000000000000
--- a/leed/SimplePie.class.php
+++ /dev/null
@@ -1,18198 +0,0 @@
-<?php
-/**
- * SimplePie
- *
- * A PHP-Based RSS and Atom Feed Framework.
- * Takes the hard work out of managing a complete RSS/Atom solution.
- *
- * Please note: This file is automatically generated by a build script. The
- * full original source is always available from http://simplepie.org/
- *
- * Copyright (c) 2004-2022, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
- * 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 of the SimplePie Team 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 HOLDERS
- * AND 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.
- *
- * @package SimplePie
- * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
- * @author Ryan Parman
- * @author Sam Sneddon
- * @author Ryan McCue
- * @link http://simplepie.org/ SimplePie
- * @license http://www.opensource.org/licenses/bsd-license.php BSD License
- */
-
-namespace SimplePie {
-
-use InvalidArgumentException;
-use Psr\SimpleCache\CacheInterface;
-use SimplePie\Cache\Base;
-use SimplePie\Cache\BaseDataCache;
-use SimplePie\Cache\CallableNameFilter;
-use SimplePie\Cache\DataCache;
-use SimplePie\Cache\NameFilter;
-use SimplePie\Cache\Psr16;
-use SimplePie\Content\Type\Sniffer;
-
-/**
- * SimplePie
- *
- * @package SimplePie
- * @subpackage API
- */
-class SimplePie
-{
-    /**
-     * SimplePie Name
-     */
-    public const NAME = 'SimplePie';
-
-    /**
-     * SimplePie Version
-     */
-    public const VERSION = '1.8.0';
-
-    /**
-     * SimplePie Website URL
-     */
-    public const URL = 'http://simplepie.org';
-
-    /**
-     * SimplePie Linkback
-     */
-    public const LINKBACK = '<a href="' . self::URL . '" title="' . self::NAME . ' ' . self::VERSION . '">' . self::NAME . '</a>';
-
-    /**
-     * No Autodiscovery
-     * @see SimplePie::set_autodiscovery_level()
-     */
-    public const LOCATOR_NONE = 0;
-
-    /**
-     * Feed Link Element Autodiscovery
-     * @see SimplePie::set_autodiscovery_level()
-     */
-    public const LOCATOR_AUTODISCOVERY = 1;
-
-    /**
-     * Local Feed Extension Autodiscovery
-     * @see SimplePie::set_autodiscovery_level()
-     */
-    public const LOCATOR_LOCAL_EXTENSION = 2;
-
-    /**
-     * Local Feed Body Autodiscovery
-     * @see SimplePie::set_autodiscovery_level()
-     */
-    public const LOCATOR_LOCAL_BODY = 4;
-
-    /**
-     * Remote Feed Extension Autodiscovery
-     * @see SimplePie::set_autodiscovery_level()
-     */
-    public const LOCATOR_REMOTE_EXTENSION = 8;
-
-    /**
-     * Remote Feed Body Autodiscovery
-     * @see SimplePie::set_autodiscovery_level()
-     */
-    public const LOCATOR_REMOTE_BODY = 16;
-
-    /**
-     * All Feed Autodiscovery
-     * @see SimplePie::set_autodiscovery_level()
-     */
-    public const LOCATOR_ALL = 31;
-
-    /**
-     * No known feed type
-     */
-    public const TYPE_NONE = 0;
-
-    /**
-     * RSS 0.90
-     */
-    public const TYPE_RSS_090 = 1;
-
-    /**
-     * RSS 0.91 (Netscape)
-     */
-    public const TYPE_RSS_091_NETSCAPE = 2;
-
-    /**
-     * RSS 0.91 (Userland)
-     */
-    public const TYPE_RSS_091_USERLAND = 4;
-
-    /**
-     * RSS 0.91 (both Netscape and Userland)
-     */
-    public const TYPE_RSS_091 = 6;
-
-    /**
-     * RSS 0.92
-     */
-    public const TYPE_RSS_092 = 8;
-
-    /**
-     * RSS 0.93
-     */
-    public const TYPE_RSS_093 = 16;
-
-    /**
-     * RSS 0.94
-     */
-    public const TYPE_RSS_094 = 32;
-
-    /**
-     * RSS 1.0
-     */
-    public const TYPE_RSS_10 = 64;
-
-    /**
-     * RSS 2.0
-     */
-    public const TYPE_RSS_20 = 128;
-
-    /**
-     * RDF-based RSS
-     */
-    public const TYPE_RSS_RDF = 65;
-
-    /**
-     * Non-RDF-based RSS (truly intended as syndication format)
-     */
-    public const TYPE_RSS_SYNDICATION = 190;
-
-    /**
-     * All RSS
-     */
-    public const TYPE_RSS_ALL = 255;
-
-    /**
-     * Atom 0.3
-     */
-    public const TYPE_ATOM_03 = 256;
-
-    /**
-     * Atom 1.0
-     */
-    public const TYPE_ATOM_10 = 512;
-
-    /**
-     * All Atom
-     */
-    public const TYPE_ATOM_ALL = 768;
-
-    /**
-     * All feed types
-     */
-    public const TYPE_ALL = 1023;
-
-    /**
-     * No construct
-     */
-    public const CONSTRUCT_NONE = 0;
-
-    /**
-     * Text construct
-     */
-    public const CONSTRUCT_TEXT = 1;
-
-    /**
-     * HTML construct
-     */
-    public const CONSTRUCT_HTML = 2;
-
-    /**
-     * XHTML construct
-     */
-    public const CONSTRUCT_XHTML = 4;
-
-    /**
-     * base64-encoded construct
-     */
-    public const CONSTRUCT_BASE64 = 8;
-
-    /**
-     * IRI construct
-     */
-    public const CONSTRUCT_IRI = 16;
-
-    /**
-     * A construct that might be HTML
-     */
-    public const CONSTRUCT_MAYBE_HTML = 32;
-
-    /**
-     * All constructs
-     */
-    public const CONSTRUCT_ALL = 63;
-
-    /**
-     * Don't change case
-     */
-    public const SAME_CASE = 1;
-
-    /**
-     * Change to lowercase
-     */
-    public const LOWERCASE = 2;
-
-    /**
-     * Change to uppercase
-     */
-    public const UPPERCASE = 4;
-
-    /**
-     * PCRE for HTML attributes
-     */
-    public const PCRE_HTML_ATTRIBUTE = '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*';
-
-    /**
-     * PCRE for XML attributes
-     */
-    public const PCRE_XML_ATTRIBUTE = '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*';
-
-    /**
-     * XML Namespace
-     */
-    public const NAMESPACE_XML = 'http://www.w3.org/XML/1998/namespace';
-
-    /**
-     * Atom 1.0 Namespace
-     */
-    public const NAMESPACE_ATOM_10 = 'http://www.w3.org/2005/Atom';
-
-    /**
-     * Atom 0.3 Namespace
-     */
-    public const NAMESPACE_ATOM_03 = 'http://purl.org/atom/ns#';
-
-    /**
-     * RDF Namespace
-     */
-    public const NAMESPACE_RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
-
-    /**
-     * RSS 0.90 Namespace
-     */
-    public const NAMESPACE_RSS_090 = 'http://my.netscape.com/rdf/simple/0.9/';
-
-    /**
-     * RSS 1.0 Namespace
-     */
-    public const NAMESPACE_RSS_10 = 'http://purl.org/rss/1.0/';
-
-    /**
-     * RSS 1.0 Content Module Namespace
-     */
-    public const NAMESPACE_RSS_10_MODULES_CONTENT = 'http://purl.org/rss/1.0/modules/content/';
-
-    /**
-     * RSS 2.0 Namespace
-     * (Stupid, I know, but I'm certain it will confuse people less with support.)
-     */
-    public const NAMESPACE_RSS_20 = '';
-
-    /**
-     * DC 1.0 Namespace
-     */
-    public const NAMESPACE_DC_10 = 'http://purl.org/dc/elements/1.0/';
-
-    /**
-     * DC 1.1 Namespace
-     */
-    public const NAMESPACE_DC_11 = 'http://purl.org/dc/elements/1.1/';
-
-    /**
-     * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
-     */
-    public const NAMESPACE_W3C_BASIC_GEO = 'http://www.w3.org/2003/01/geo/wgs84_pos#';
-
-    /**
-     * GeoRSS Namespace
-     */
-    public const NAMESPACE_GEORSS = 'http://www.georss.org/georss';
-
-    /**
-     * Media RSS Namespace
-     */
-    public const NAMESPACE_MEDIARSS = 'http://search.yahoo.com/mrss/';
-
-    /**
-     * Wrong Media RSS Namespace. Caused by a long-standing typo in the spec.
-     */
-    public const NAMESPACE_MEDIARSS_WRONG = 'http://search.yahoo.com/mrss';
-
-    /**
-     * Wrong Media RSS Namespace #2. New namespace introduced in Media RSS 1.5.
-     */
-    public const NAMESPACE_MEDIARSS_WRONG2 = 'http://video.search.yahoo.com/mrss';
-
-    /**
-     * Wrong Media RSS Namespace #3. A possible typo of the Media RSS 1.5 namespace.
-     */
-    public const NAMESPACE_MEDIARSS_WRONG3 = 'http://video.search.yahoo.com/mrss/';
-
-    /**
-     * Wrong Media RSS Namespace #4. New spec location after the RSS Advisory Board takes it over, but not a valid namespace.
-     */
-    public const NAMESPACE_MEDIARSS_WRONG4 = 'http://www.rssboard.org/media-rss';
-
-    /**
-     * Wrong Media RSS Namespace #5. A possible typo of the RSS Advisory Board URL.
-     */
-    public const NAMESPACE_MEDIARSS_WRONG5 = 'http://www.rssboard.org/media-rss/';
-
-    /**
-     * iTunes RSS Namespace
-     */
-    public const NAMESPACE_ITUNES = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
-
-    /**
-     * XHTML Namespace
-     */
-    public const NAMESPACE_XHTML = 'http://www.w3.org/1999/xhtml';
-
-    /**
-     * IANA Link Relations Registry
-     */
-    public const IANA_LINK_RELATIONS_REGISTRY = 'http://www.iana.org/assignments/relation/';
-
-    /**
-     * No file source
-     */
-    public const FILE_SOURCE_NONE = 0;
-
-    /**
-     * Remote file source
-     */
-    public const FILE_SOURCE_REMOTE = 1;
-
-    /**
-     * Local file source
-     */
-    public const FILE_SOURCE_LOCAL = 2;
-
-    /**
-     * fsockopen() file source
-     */
-    public const FILE_SOURCE_FSOCKOPEN = 4;
-
-    /**
-     * cURL file source
-     */
-    public const FILE_SOURCE_CURL = 8;
-
-    /**
-     * file_get_contents() file source
-     */
-    public const FILE_SOURCE_FILE_GET_CONTENTS = 16;
-
-    /**
-     * @var array Raw data
-     * @access private
-     */
-    public $data = [];
-
-    /**
-     * @var mixed Error string
-     * @access private
-     */
-    public $error;
-
-    /**
-     * @var int HTTP status code
-     * @see SimplePie::status_code()
-     * @access private
-     */
-    public $status_code = 0;
-
-    /**
-     * @var object Instance of \SimplePie\Sanitize (or other class)
-     * @see SimplePie::set_sanitize_class()
-     * @access private
-     */
-    public $sanitize;
-
-    /**
-     * @var string SimplePie Useragent
-     * @see SimplePie::set_useragent()
-     * @access private
-     */
-    public $useragent = '';
-
-    /**
-     * @var string Feed URL
-     * @see SimplePie::set_feed_url()
-     * @access private
-     */
-    public $feed_url;
-
-    /**
-     * @var string Original feed URL, or new feed URL iff HTTP 301 Moved Permanently
-     * @see SimplePie::subscribe_url()
-     * @access private
-     */
-    public $permanent_url = null;
-
-    /**
-     * @var object Instance of \SimplePie\File to use as a feed
-     * @see SimplePie::set_file()
-     * @access private
-     */
-    public $file;
-
-    /**
-     * @var string Raw feed data
-     * @see SimplePie::set_raw_data()
-     * @access private
-     */
-    public $raw_data;
-
-    /**
-     * @var int Timeout for fetching remote files
-     * @see SimplePie::set_timeout()
-     * @access private
-     */
-    public $timeout = 10;
-
-    /**
-     * @var array Custom curl options
-     * @see SimplePie::set_curl_options()
-     * @access private
-     */
-    public $curl_options = [];
-
-    /**
-     * @var bool Forces fsockopen() to be used for remote files instead
-     * of cURL, even if a new enough version is installed
-     * @see SimplePie::force_fsockopen()
-     * @access private
-     */
-    public $force_fsockopen = false;
-
-    /**
-     * @var bool Force the given data/URL to be treated as a feed no matter what
-     * it appears like
-     * @see SimplePie::force_feed()
-     * @access private
-     */
-    public $force_feed = false;
-
-    /**
-     * @var bool Enable/Disable Caching
-     * @see SimplePie::enable_cache()
-     * @access private
-     */
-    private $enable_cache = true;
-
-    /**
-     * @var DataCache|null
-     * @see SimplePie::set_cache()
-     */
-    private $cache = null;
-
-    /**
-     * @var NameFilter
-     * @see SimplePie::set_cache_namefilter()
-     */
-    private $cache_namefilter;
-
-    /**
-     * @var bool Force SimplePie to fallback to expired cache, if enabled,
-     * when feed is unavailable.
-     * @see SimplePie::force_cache_fallback()
-     * @access private
-     */
-    public $force_cache_fallback = false;
-
-    /**
-     * @var int Cache duration (in seconds)
-     * @see SimplePie::set_cache_duration()
-     * @access private
-     */
-    public $cache_duration = 3600;
-
-    /**
-     * @var int Auto-discovery cache duration (in seconds)
-     * @see SimplePie::set_autodiscovery_cache_duration()
-     * @access private
-     */
-    public $autodiscovery_cache_duration = 604800; // 7 Days.
-
-    /**
-     * @var string Cache location (relative to executing script)
-     * @see SimplePie::set_cache_location()
-     * @access private
-     */
-    public $cache_location = './cache';
-
-    /**
-     * @var string Function that creates the cache filename
-     * @see SimplePie::set_cache_name_function()
-     * @access private
-     */
-    public $cache_name_function = 'md5';
-
-    /**
-     * @var bool Reorder feed by date descending
-     * @see SimplePie::enable_order_by_date()
-     * @access private
-     */
-    public $order_by_date = true;
-
-    /**
-     * @var mixed Force input encoding to be set to the follow value
-     * (false, or anything type-cast to false, disables this feature)
-     * @see SimplePie::set_input_encoding()
-     * @access private
-     */
-    public $input_encoding = false;
-
-    /**
-     * @var int Feed Autodiscovery Level
-     * @see SimplePie::set_autodiscovery_level()
-     * @access private
-     */
-    public $autodiscovery = self::LOCATOR_ALL;
-
-    /**
-     * Class registry object
-     *
-     * @var \SimplePie\Registry
-     */
-    public $registry;
-
-    /**
-     * @var int Maximum number of feeds to check with autodiscovery
-     * @see SimplePie::set_max_checked_feeds()
-     * @access private
-     */
-    public $max_checked_feeds = 10;
-
-    /**
-     * @var array All the feeds found during the autodiscovery process
-     * @see SimplePie::get_all_discovered_feeds()
-     * @access private
-     */
-    public $all_discovered_feeds = [];
-
-    /**
-     * @var string Web-accessible path to the handler_image.php file.
-     * @see SimplePie::set_image_handler()
-     * @access private
-     */
-    public $image_handler = '';
-
-    /**
-     * @var array Stores the URLs when multiple feeds are being initialized.
-     * @see SimplePie::set_feed_url()
-     * @access private
-     */
-    public $multifeed_url = [];
-
-    /**
-     * @var array Stores SimplePie objects when multiple feeds initialized.
-     * @access private
-     */
-    public $multifeed_objects = [];
-
-    /**
-     * @var array Stores the get_object_vars() array for use with multifeeds.
-     * @see SimplePie::set_feed_url()
-     * @access private
-     */
-    public $config_settings = null;
-
-    /**
-     * @var integer Stores the number of items to return per-feed with multifeeds.
-     * @see SimplePie::set_item_limit()
-     * @access private
-     */
-    public $item_limit = 0;
-
-    /**
-     * @var bool Stores if last-modified and/or etag headers were sent with the
-     * request when checking a feed.
-     */
-    public $check_modified = false;
-
-    /**
-     * @var array Stores the default attributes to be stripped by strip_attributes().
-     * @see SimplePie::strip_attributes()
-     * @access private
-     */
-    public $strip_attributes = ['bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'];
-
-    /**
-     * @var array Stores the default attributes to add to different tags by add_attributes().
-     * @see SimplePie::add_attributes()
-     * @access private
-     */
-    public $add_attributes = ['audio' => ['preload' => 'none'], 'iframe' => ['sandbox' => 'allow-scripts allow-same-origin'], 'video' => ['preload' => 'none']];
-
-    /**
-     * @var array Stores the default tags to be stripped by strip_htmltags().
-     * @see SimplePie::strip_htmltags()
-     * @access private
-     */
-    public $strip_htmltags = ['base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'];
-
-    /**
-     * @var array Stores the default attributes to be renamed by rename_attributes().
-     * @see SimplePie::rename_attributes()
-     * @access private
-     */
-    public $rename_attributes = [];
-
-    /**
-     * @var bool Should we throw exceptions, or use the old-style error property?
-     * @access private
-     */
-    public $enable_exceptions = false;
-
-    /**
-     * The SimplePie class contains feed level data and options
-     *
-     * To use SimplePie, create the SimplePie object with no parameters. You can
-     * then set configuration options using the provided methods. After setting
-     * them, you must initialise the feed using $feed->init(). At that point the
-     * object's methods and properties will be available to you.
-     *
-     * Previously, it was possible to pass in the feed URL along with cache
-     * options directly into the constructor. This has been removed as of 1.3 as
-     * it caused a lot of confusion.
-     *
-     * @since 1.0 Preview Release
-     */
-    public function __construct()
-    {
-        if (version_compare(PHP_VERSION, '7.2', '<')) {
-            trigger_error('Please upgrade to PHP 7.2 or newer.');
-            die();
-        }
-
-        $this->set_useragent();
-
-        $this->set_cache_namefilter(new CallableNameFilter($this->cache_name_function));
-
-        // Other objects, instances created here so we can set options on them
-        $this->sanitize = new \SimplePie\Sanitize();
-        $this->registry = new \SimplePie\Registry();
-
-        if (func_num_args() > 0) {
-            trigger_error('Passing parameters to the constructor is no longer supported. Please use set_feed_url(), set_cache_location(), and set_cache_duration() directly.', \E_USER_DEPRECATED);
-
-            $args = func_get_args();
-            switch (count($args)) {
-                case 3:
-                    $this->set_cache_duration($args[2]);
-                    // no break
-                case 2:
-                    $this->set_cache_location($args[1]);
-                    // no break
-                case 1:
-                    $this->set_feed_url($args[0]);
-                    $this->init();
-            }
-        }
-    }
-
-    /**
-     * Used for converting object to a string
-     */
-    public function __toString()
-    {
-        return md5(serialize($this->data));
-    }
-
-    /**
-     * Remove items that link back to this before destroying this object
-     */
-    public function __destruct()
-    {
-        if (!gc_enabled()) {
-            if (!empty($this->data['items'])) {
-                foreach ($this->data['items'] as $item) {
-                    $item->__destruct();
-                }
-                unset($item, $this->data['items']);
-            }
-            if (!empty($this->data['ordered_items'])) {
-                foreach ($this->data['ordered_items'] as $item) {
-                    $item->__destruct();
-                }
-                unset($item, $this->data['ordered_items']);
-            }
-        }
-    }
-
-    /**
-     * Force the given data/URL to be treated as a feed
-     *
-     * This tells SimplePie to ignore the content-type provided by the server.
-     * Be careful when using this option, as it will also disable autodiscovery.
-     *
-     * @since 1.1
-     * @param bool $enable Force the given data/URL to be treated as a feed
-     */
-    public function force_feed($enable = false)
-    {
-        $this->force_feed = (bool) $enable;
-    }
-
-    /**
-     * Set the URL of the feed you want to parse
-     *
-     * This allows you to enter the URL of the feed you want to parse, or the
-     * website you want to try to use auto-discovery on. This takes priority
-     * over any set raw data.
-     *
-     * You can set multiple feeds to mash together by passing an array instead
-     * of a string for the $url. Remember that with each additional feed comes
-     * additional processing and resources.
-     *
-     * @since 1.0 Preview Release
-     * @see set_raw_data()
-     * @param string|array $url This is the URL (or array of URLs) that you want to parse.
-     */
-    public function set_feed_url($url)
-    {
-        $this->multifeed_url = [];
-        if (is_array($url)) {
-            foreach ($url as $value) {
-                $this->multifeed_url[] = $this->registry->call(Misc::class, 'fix_protocol', [$value, 1]);
-            }
-        } else {
-            $this->feed_url = $this->registry->call(Misc::class, 'fix_protocol', [$url, 1]);
-            $this->permanent_url = $this->feed_url;
-        }
-    }
-
-    /**
-     * Set an instance of {@see \SimplePie\File} to use as a feed
-     *
-     * @param \SimplePie\File &$file
-     * @return bool True on success, false on failure
-     */
-    public function set_file(&$file)
-    {
-        if ($file instanceof \SimplePie\File) {
-            $this->feed_url = $file->url;
-            $this->permanent_url = $this->feed_url;
-            $this->file =& $file;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Set the raw XML data to parse
-     *
-     * Allows you to use a string of RSS/Atom data instead of a remote feed.
-     *
-     * If you have a feed available as a string in PHP, you can tell SimplePie
-     * to parse that data string instead of a remote feed. Any set feed URL
-     * takes precedence.
-     *
-     * @since 1.0 Beta 3
-     * @param string $data RSS or Atom data as a string.
-     * @see set_feed_url()
-     */
-    public function set_raw_data($data)
-    {
-        $this->raw_data = $data;
-    }
-
-    /**
-     * Set the default timeout for fetching remote feeds
-     *
-     * This allows you to change the maximum time the feed's server to respond
-     * and send the feed back.
-     *
-     * @since 1.0 Beta 3
-     * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
-     */
-    public function set_timeout($timeout = 10)
-    {
-        $this->timeout = (int) $timeout;
-    }
-
-    /**
-     * Set custom curl options
-     *
-     * This allows you to change default curl options
-     *
-     * @since 1.0 Beta 3
-     * @param array $curl_options Curl options to add to default settings
-     */
-    public function set_curl_options(array $curl_options = [])
-    {
-        $this->curl_options = $curl_options;
-    }
-
-    /**
-     * Force SimplePie to use fsockopen() instead of cURL
-     *
-     * @since 1.0 Beta 3
-     * @param bool $enable Force fsockopen() to be used
-     */
-    public function force_fsockopen($enable = false)
-    {
-        $this->force_fsockopen = (bool) $enable;
-    }
-
-    /**
-     * Enable/disable caching in SimplePie.
-     *
-     * This option allows you to disable caching all-together in SimplePie.
-     * However, disabling the cache can lead to longer load times.
-     *
-     * @since 1.0 Preview Release
-     * @param bool $enable Enable caching
-     */
-    public function enable_cache($enable = true)
-    {
-        $this->enable_cache = (bool) $enable;
-    }
-
-    /**
-     * Set a PSR-16 implementation as cache
-     *
-     * @param CacheInterface $psr16cache The PSR-16 cache implementation
-     *
-     * @return void
-     */
-    public function set_cache(CacheInterface $cache)
-    {
-        $this->cache = new Psr16($cache);
-    }
-
-    /**
-     * SimplePie to continue to fall back to expired cache, if enabled, when
-     * feed is unavailable.
-     *
-     * This tells SimplePie to ignore any file errors and fall back to cache
-     * instead. This only works if caching is enabled and cached content
-     * still exists.
-     *
-     * @deprecated since SimplePie 1.8.0, expired cache will not be used anymore.
-     *
-     * @param bool $enable Force use of cache on fail.
-     */
-    public function force_cache_fallback($enable = false)
-    {
-        // @trigger_error(sprintf('SimplePie\SimplePie::force_cache_fallback() is deprecated since SimplePie 1.8.0, expired cache will not be used anymore.'), \E_USER_DEPRECATED);
-        $this->force_cache_fallback = (bool) $enable;
-    }
-
-    /**
-     * Set the length of time (in seconds) that the contents of a feed will be
-     * cached
-     *
-     * @param int $seconds The feed content cache duration
-     */
-    public function set_cache_duration($seconds = 3600)
-    {
-        $this->cache_duration = (int) $seconds;
-    }
-
-    /**
-     * Set the length of time (in seconds) that the autodiscovered feed URL will
-     * be cached
-     *
-     * @param int $seconds The autodiscovered feed URL cache duration.
-     */
-    public function set_autodiscovery_cache_duration($seconds = 604800)
-    {
-        $this->autodiscovery_cache_duration = (int) $seconds;
-    }
-
-    /**
-     * Set the file system location where the cached files should be stored
-     *
-     * @deprecated since SimplePie 1.8.0, use \SimplePie\SimplePie::set_cache() instead.
-     *
-     * @param string $location The file system location.
-     */
-    public function set_cache_location($location = './cache')
-    {
-        // @trigger_error(sprintf('SimplePie\SimplePie::set_cache_location() is deprecated since SimplePie 1.8.0, please use "SimplePie\SimplePie::set_cache()" instead.'), \E_USER_DEPRECATED);
-        $this->cache_location = (string) $location;
-    }
-
-    /**
-     * Return the filename (i.e. hash, without path and without extension) of the file to cache a given URL.
-     *
-     * @param string $url The URL of the feed to be cached.
-     * @return string A filename (i.e. hash, without path and without extension).
-     */
-    public function get_cache_filename($url)
-    {
-        // Append custom parameters to the URL to avoid cache pollution in case of multiple calls with different parameters.
-        $url .= $this->force_feed ? '#force_feed' : '';
-        $options = [];
-        if ($this->timeout != 10) {
-            $options[CURLOPT_TIMEOUT] = $this->timeout;
-        }
-        if ($this->useragent !== \SimplePie\Misc::get_default_useragent()) {
-            $options[CURLOPT_USERAGENT] = $this->useragent;
-        }
-        if (!empty($this->curl_options)) {
-            foreach ($this->curl_options as $k => $v) {
-                $options[$k] = $v;
-            }
-        }
-        if (!empty($options)) {
-            ksort($options);
-            $url .= '#' . urlencode(var_export($options, true));
-        }
-
-        return $this->cache_namefilter->filter($url);
-    }
-
-    /**
-     * Set whether feed items should be sorted into reverse chronological order
-     *
-     * @param bool $enable Sort as reverse chronological order.
-     */
-    public function enable_order_by_date($enable = true)
-    {
-        $this->order_by_date = (bool) $enable;
-    }
-
-    /**
-     * Set the character encoding used to parse the feed
-     *
-     * This overrides the encoding reported by the feed, however it will fall
-     * back to the normal encoding detection if the override fails
-     *
-     * @param string $encoding Character encoding
-     */
-    public function set_input_encoding($encoding = false)
-    {
-        if ($encoding) {
-            $this->input_encoding = (string) $encoding;
-        } else {
-            $this->input_encoding = false;
-        }
-    }
-
-    /**
-     * Set how much feed autodiscovery to do
-     *
-     * @see \SimplePie\SimplePie::LOCATOR_NONE
-     * @see \SimplePie\SimplePie::LOCATOR_AUTODISCOVERY
-     * @see \SimplePie\SimplePie::LOCATOR_LOCAL_EXTENSION
-     * @see \SimplePie\SimplePie::LOCATOR_LOCAL_BODY
-     * @see \SimplePie\SimplePie::LOCATOR_REMOTE_EXTENSION
-     * @see \SimplePie\SimplePie::LOCATOR_REMOTE_BODY
-     * @see \SimplePie\SimplePie::LOCATOR_ALL
-     * @param int $level Feed Autodiscovery Level (level can be a combination of the above constants, see bitwise OR operator)
-     */
-    public function set_autodiscovery_level($level = self::LOCATOR_ALL)
-    {
-        $this->autodiscovery = (int) $level;
-    }
-
-    /**
-     * Get the class registry
-     *
-     * Use this to override SimplePie's default classes
-     * @see \SimplePie\Registry
-     *
-     * @return Registry
-     */
-    public function &get_registry()
-    {
-        return $this->registry;
-    }
-
-    /**
-     * Set which class SimplePie uses for caching
-     *
-     * @deprecated since SimplePie 1.3, use {@see set_cache()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_cache_class($class = Cache::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::set_cache()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Cache::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for auto-discovery
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_locator_class($class = Locator::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Locator::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for XML parsing
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_parser_class($class = Parser::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Parser::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for remote file fetching
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_file_class($class = File::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(File::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for data sanitization
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_sanitize_class($class = Sanitize::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Sanitize::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for handling feed items
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_item_class($class = Item::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Item::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for handling author data
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_author_class($class = Author::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Author::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for handling category data
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_category_class($class = Category::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Category::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for feed enclosures
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_enclosure_class($class = Enclosure::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Enclosure::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for `<media:text>` captions
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_caption_class($class = Caption::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Caption::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for `<media:copyright>`
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_copyright_class($class = Copyright::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Copyright::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for `<media:credit>`
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_credit_class($class = Credit::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Credit::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for `<media:rating>`
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_rating_class($class = Rating::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Rating::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for `<media:restriction>`
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_restriction_class($class = Restriction::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Restriction::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses for content-type sniffing
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_content_type_sniffer_class($class = Sniffer::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Sniffer::class, $class, true);
-    }
-
-    /**
-     * Set which class SimplePie uses item sources
-     *
-     * @deprecated since SimplePie 1.3, use {@see get_registry()} instead
-     *
-     * @param string $class Name of custom class
-     *
-     * @return boolean True on success, false otherwise
-     */
-    public function set_source_class($class = Source::class)
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        return $this->registry->register(Source::class, $class, true);
-    }
-
-    /**
-     * Set the user agent string
-     *
-     * @param string $ua New user agent string.
-     */
-    public function set_useragent($ua = null)
-    {
-        if ($ua === null) {
-            $ua = \SimplePie\Misc::get_default_useragent();
-        }
-
-        $this->useragent = (string) $ua;
-    }
-
-    /**
-     * Set a namefilter to modify the cache filename with
-     *
-     * @param NameFilter $filter
-     *
-     * @return void
-     */
-    public function set_cache_namefilter(NameFilter $filter): void
-    {
-        $this->cache_namefilter = $filter;
-    }
-
-    /**
-     * Set callback function to create cache filename with
-     *
-     * @deprecated since SimplePie 1.8.0, use {@see set_cache_namefilter()} instead
-     *
-     * @param mixed $function Callback function
-     */
-    public function set_cache_name_function($function = 'md5')
-    {
-        // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.8.0, please use "SimplePie\SimplePie::set_cache_namefilter()" instead.', __METHOD__), \E_USER_DEPRECATED);
-
-        if (is_callable($function)) {
-            $this->cache_name_function = $function;
-
-            $this->set_cache_namefilter(new CallableNameFilter($this->cache_name_function));
-        }
-    }
-
-    /**
-     * Set options to make SP as fast as possible
-     *
-     * Forgoes a substantial amount of data sanitization in favor of speed. This
-     * turns SimplePie into a dumb parser of feeds.
-     *
-     * @param bool $set Whether to set them or not
-     */
-    public function set_stupidly_fast($set = false)
-    {
-        if ($set) {
-            $this->enable_order_by_date(false);
-            $this->remove_div(false);
-            $this->strip_comments(false);
-            $this->strip_htmltags(false);
-            $this->strip_attributes(false);
-            $this->add_attributes(false);
-            $this->set_image_handler(false);
-            $this->set_https_domains([]);
-        }
-    }
-
-    /**
-     * Set maximum number of feeds to check with autodiscovery
-     *
-     * @param int $max Maximum number of feeds to check
-     */
-    public function set_max_checked_feeds($max = 10)
-    {
-        $this->max_checked_feeds = (int) $max;
-    }
-
-    public function remove_div($enable = true)
-    {
-        $this->sanitize->remove_div($enable);
-    }
-
-    public function strip_htmltags($tags = '', $encode = null)
-    {
-        if ($tags === '') {
-            $tags = $this->strip_htmltags;
-        }
-        $this->sanitize->strip_htmltags($tags);
-        if ($encode !== null) {
-            $this->sanitize->encode_instead_of_strip($tags);
-        }
-    }
-
-    public function encode_instead_of_strip($enable = true)
-    {
-        $this->sanitize->encode_instead_of_strip($enable);
-    }
-
-    public function rename_attributes($attribs = '')
-    {
-        if ($attribs === '') {
-            $attribs = $this->rename_attributes;
-        }
-        $this->sanitize->rename_attributes($attribs);
-    }
-
-    public function strip_attributes($attribs = '')
-    {
-        if ($attribs === '') {
-            $attribs = $this->strip_attributes;
-        }
-        $this->sanitize->strip_attributes($attribs);
-    }
-
-    public function add_attributes($attribs = '')
-    {
-        if ($attribs === '') {
-            $attribs = $this->add_attributes;
-        }
-        $this->sanitize->add_attributes($attribs);
-    }
-
-    /**
-     * Set the output encoding
-     *
-     * Allows you to override SimplePie's output to match that of your webpage.
-     * This is useful for times when your webpages are not being served as
-     * UTF-8. This setting will be obeyed by {@see handle_content_type()}, and
-     * is similar to {@see set_input_encoding()}.
-     *
-     * It should be noted, however, that not all character encodings can support
-     * all characters. If your page is being served as ISO-8859-1 and you try
-     * to display a Japanese feed, you'll likely see garbled characters.
-     * Because of this, it is highly recommended to ensure that your webpages
-     * are served as UTF-8.
-     *
-     * The number of supported character encodings depends on whether your web
-     * host supports {@link http://php.net/mbstring mbstring},
-     * {@link http://php.net/iconv iconv}, or both. See
-     * {@link http://simplepie.org/wiki/faq/Supported_Character_Encodings} for
-     * more information.
-     *
-     * @param string $encoding
-     */
-    public function set_output_encoding($encoding = 'UTF-8')
-    {
-        $this->sanitize->set_output_encoding($encoding);
-    }
-
-    public function strip_comments($strip = false)
-    {
-        $this->sanitize->strip_comments($strip);
-    }
-
-    /**
-     * Set element/attribute key/value pairs of HTML attributes
-     * containing URLs that need to be resolved relative to the feed
-     *
-     * Defaults to |a|@href, |area|@href, |blockquote|@cite, |del|@cite,
-     * |form|@action, |img|@longdesc, |img|@src, |input|@src, |ins|@cite,
-     * |q|@cite
-     *
-     * @since 1.0
-     * @param array|null $element_attribute Element/attribute key/value pairs, null for default
-     */
-    public function set_url_replacements($element_attribute = null)
-    {
-        $this->sanitize->set_url_replacements($element_attribute);
-    }
-
-    /**
-     * Set the list of domains for which to force HTTPS.
-     * @see \SimplePie\Sanitize::set_https_domains()
-     * @param array List of HTTPS domains. Example array('biz', 'example.com', 'example.org', 'www.example.net').
-     */
-    public function set_https_domains($domains = [])
-    {
-        if (is_array($domains)) {
-            $this->sanitize->set_https_domains($domains);
-        }
-    }
-
-    /**
-     * Set the handler to enable the display of cached images.
-     *
-     * @param string $page Web-accessible path to the handler_image.php file.
-     * @param string $qs The query string that the value should be passed to.
-     */
-    public function set_image_handler($page = false, $qs = 'i')
-    {
-        if ($page !== false) {
-            $this->sanitize->set_image_handler($page . '?' . $qs . '=');
-        } else {
-            $this->image_handler = '';
-        }
-    }
-
-    /**
-     * Set the limit for items returned per-feed with multifeeds
-     *
-     * @param integer $limit The maximum number of items to return.
-     */
-    public function set_item_limit($limit = 0)
-    {
-        $this->item_limit = (int) $limit;
-    }
-
-    /**
-     * Enable throwing exceptions
-     *
-     * @param boolean $enable Should we throw exceptions, or use the old-style error property?
-     */
-    public function enable_exceptions($enable = true)
-    {
-        $this->enable_exceptions = $enable;
-    }
-
-    /**
-     * Initialize the feed object
-     *
-     * This is what makes everything happen. Period. This is where all of the
-     * configuration options get processed, feeds are fetched, cached, and
-     * parsed, and all of that other good stuff.
-     *
-     * @return boolean True if successful, false otherwise
-     */
-    public function init()
-    {
-        // Check absolute bare minimum requirements.
-        if (!extension_loaded('xml') || !extension_loaded('pcre')) {
-            $this->error = 'XML or PCRE extensions not loaded!';
-            return false;
-        }
-        // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader.
-        elseif (!extension_loaded('xmlreader')) {
-            static $xml_is_sane = null;
-            if ($xml_is_sane === null) {
-                $parser_check = xml_parser_create();
-                xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
-                xml_parser_free($parser_check);
-                $xml_is_sane = isset($values[0]['value']);
-            }
-            if (!$xml_is_sane) {
-                return false;
-            }
-        }
-
-        // The default sanitize class gets set in the constructor, check if it has
-        // changed.
-        if ($this->registry->get_class(Sanitize::class) !== 'SimplePie\Sanitize') {
-            $this->sanitize = $this->registry->create(Sanitize::class);
-        }
-        if (method_exists($this->sanitize, 'set_registry')) {
-            $this->sanitize->set_registry($this->registry);
-        }
-
-        // Pass whatever was set with config options over to the sanitizer.
-        // Pass the classes in for legacy support; new classes should use the registry instead
-        $this->sanitize->pass_cache_data(
-            $this->enable_cache,
-            $this->cache_location,
-            $this->cache_namefilter,
-            $this->registry->get_class(Cache::class),
-            $this->cache
-        );
-        $this->sanitize->pass_file_data($this->registry->get_class(File::class), $this->timeout, $this->useragent, $this->force_fsockopen, $this->curl_options);
-
-        if (!empty($this->multifeed_url)) {
-            $i = 0;
-            $success = 0;
-            $this->multifeed_objects = [];
-            $this->error = [];
-            foreach ($this->multifeed_url as $url) {
-                $this->multifeed_objects[$i] = clone $this;
-                $this->multifeed_objects[$i]->set_feed_url($url);
-                $single_success = $this->multifeed_objects[$i]->init();
-                $success |= $single_success;
-                if (!$single_success) {
-                    $this->error[$i] = $this->multifeed_objects[$i]->error();
-                }
-                $i++;
-            }
-            return (bool) $success;
-        } elseif ($this->feed_url === null && $this->raw_data === null) {
-            return false;
-        }
-
-        $this->error = null;
-        $this->data = [];
-        $this->check_modified = false;
-        $this->multifeed_objects = [];
-        $cache = false;
-
-        if ($this->feed_url !== null) {
-            $parsed_feed_url = $this->registry->call(Misc::class, 'parse_url', [$this->feed_url]);
-
-            // Decide whether to enable caching
-            if ($this->enable_cache && $parsed_feed_url['scheme'] !== '') {
-                $cache = $this->get_cache($this->feed_url);
-            }
-
-            // Fetch the data via \SimplePie\File into $this->raw_data
-            if (($fetched = $this->fetch_data($cache)) === true) {
-                return true;
-            } elseif ($fetched === false) {
-                return false;
-            }
-
-            [$headers, $sniffed] = $fetched;
-        }
-
-        // Empty response check
-        if (empty($this->raw_data)) {
-            $this->error = "A feed could not be found at `$this->feed_url`. Empty body.";
-            $this->registry->call(Misc::class, 'error', [$this->error, E_USER_NOTICE, __FILE__, __LINE__]);
-            return false;
-        }
-
-        // Set up array of possible encodings
-        $encodings = [];
-
-        // First check to see if input has been overridden.
-        if ($this->input_encoding !== false) {
-            $encodings[] = strtoupper($this->input_encoding);
-        }
-
-        $application_types = ['application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity'];
-        $text_types = ['text/xml', 'text/xml-external-parsed-entity'];
-
-        // RFC 3023 (only applies to sniffed content)
-        if (isset($sniffed)) {
-            if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml') {
-                if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) {
-                    $encodings[] = strtoupper($charset[1]);
-                }
-                $encodings = array_merge($encodings, $this->registry->call(Misc::class, 'xml_encoding', [$this->raw_data, &$this->registry]));
-                $encodings[] = 'UTF-8';
-            } elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml') {
-                if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) {
-                    $encodings[] = strtoupper($charset[1]);
-                }
-                $encodings[] = 'US-ASCII';
-            }
-            // Text MIME-type default
-            elseif (substr($sniffed, 0, 5) === 'text/') {
-                $encodings[] = 'UTF-8';
-            }
-        }
-
-        // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
-        $encodings = array_merge($encodings, $this->registry->call(Misc::class, 'xml_encoding', [$this->raw_data, &$this->registry]));
-        $encodings[] = 'UTF-8';
-        $encodings[] = 'ISO-8859-1';
-
-        // There's no point in trying an encoding twice
-        $encodings = array_unique($encodings);
-
-        // Loop through each possible encoding, till we return something, or run out of possibilities
-        foreach ($encodings as $encoding) {
-            // Change the encoding to UTF-8 (as we always use UTF-8 internally)
-            if ($utf8_data = $this->registry->call(Misc::class, 'change_encoding', [$this->raw_data, $encoding, 'UTF-8'])) {
-                // Create new parser
-                $parser = $this->registry->create(Parser::class);
-
-                // If it's parsed fine
-                if ($parser->parse($utf8_data, 'UTF-8', $this->permanent_url)) {
-                    $this->data = $parser->get_data();
-                    if (!($this->get_type() & ~self::TYPE_NONE)) {
-                        $this->error = "A feed could not be found at `$this->feed_url`. This does not appear to be a valid RSS or Atom feed.";
-                        $this->registry->call(Misc::class, 'error', [$this->error, E_USER_NOTICE, __FILE__, __LINE__]);
-                        return false;
-                    }
-
-                    if (isset($headers)) {
-                        $this->data['headers'] = $headers;
-                    }
-                    $this->data['build'] = \SimplePie\Misc::get_build();
-
-                    // Cache the file if caching is enabled
-                    $this->data['cache_expiration_time'] = $this->cache_duration + time();
-                    if ($cache && ! $cache->set_data($this->get_cache_filename($this->feed_url), $this->data, $this->cache_duration)) {
-                        trigger_error("$this->cache_location is not writable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
-                    }
-                    return true;
-                }
-            }
-        }
-
-        if (isset($parser)) {
-            // We have an error, just set \SimplePie\Misc::error to it and quit
-            $this->error = $this->feed_url;
-            $this->error .= sprintf(' is invalid XML, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
-        } else {
-            $this->error = 'The data could not be converted to UTF-8.';
-            if (!extension_loaded('mbstring') && !extension_loaded('iconv') && !class_exists('\UConverter')) {
-                $this->error .= ' You MUST have either the iconv, mbstring or intl (PHP 5.5+) extension installed and enabled.';
-            } else {
-                $missingExtensions = [];
-                if (!extension_loaded('iconv')) {
-                    $missingExtensions[] = 'iconv';
-                }
-                if (!extension_loaded('mbstring')) {
-                    $missingExtensions[] = 'mbstring';
-                }
-                if (!class_exists('\UConverter')) {
-                    $missingExtensions[] = 'intl (PHP 5.5+)';
-                }
-                $this->error .= ' Try installing/enabling the ' . implode(' or ', $missingExtensions) . ' extension.';
-            }
-        }
-
-        $this->registry->call(Misc::class, 'error', [$this->error, E_USER_NOTICE, __FILE__, __LINE__]);
-
-        return false;
-    }
-
-    /**
-     * Fetch the data via \SimplePie\File
-     *
-     * If the data is already cached, attempt to fetch it from there instead
-     * @param Base|DataCache|false $cache Cache handler, or false to not load from the cache
-     * @return array|true Returns true if the data was loaded from the cache, or an array of HTTP headers and sniffed type
-     */
-    protected function fetch_data(&$cache)
-    {
-        if (is_object($cache) && $cache instanceof Base) {
-            // @trigger_error(sprintf('Providing $cache as "\SimplePie\Cache\Base" in %s() is deprecated since SimplePie 1.8.0, please provide "\SimplePie\Cache\DataCache" implementation instead.', __METHOD__), \E_USER_DEPRECATED);
-            $cache = new BaseDataCache($cache);
-        }
-
-        if ($cache !== false && ! $cache instanceof DataCache) {
-            throw new InvalidArgumentException(sprintf(
-                '%s(): Argument #1 ($cache) must be of type %s|false',
-                __METHOD__,
-                DataCache::class
-            ), 1);
-        }
-
-        $cacheKey = $this->get_cache_filename($this->feed_url);
-
-        // If it's enabled, use the cache
-        if ($cache) {
-            // Load the Cache
-            $this->data = $cache->get_data($cacheKey, []);
-
-            if (!empty($this->data)) {
-                // If the cache is for an outdated build of SimplePie
-                if (!isset($this->data['build']) || $this->data['build'] !== \SimplePie\Misc::get_build()) {
-                    $cache->delete_data($cacheKey);
-                    $this->data = [];
-                }
-                // If we've hit a collision just rerun it with caching disabled
-                elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url) {
-                    $cache = false;
-                    $this->data = [];
-                }
-                // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
-                elseif (isset($this->data['feed_url'])) {
-                    // Do not need to do feed autodiscovery yet.
-                    if ($this->data['feed_url'] !== $this->data['url']) {
-                        $this->set_feed_url($this->data['feed_url']);
-                        $this->data['url'] = $this->data['feed_url'];
-
-                        $cache->set_data($this->get_cache_filename($this->feed_url), $this->data, $this->autodiscovery_cache_duration);
-
-                        return $this->init();
-                    }
-
-                    $cache->delete_data($this->get_cache_filename($this->feed_url));
-                    $this->data = [];
-                }
-                // Check if the cache has been updated
-                elseif (isset($this->data['cache_expiration_time']) && $this->data['cache_expiration_time'] > time()) {
-                    // Want to know if we tried to send last-modified and/or etag headers
-                    // when requesting this file. (Note that it's up to the file to
-                    // support this, but we don't always send the headers either.)
-                    $this->check_modified = true;
-                    if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag'])) {
-                        $headers = [
-                            'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
-                        ];
-                        if (isset($this->data['headers']['last-modified'])) {
-                            $headers['if-modified-since'] = $this->data['headers']['last-modified'];
-                        }
-                        if (isset($this->data['headers']['etag'])) {
-                            $headers['if-none-match'] = $this->data['headers']['etag'];
-                        }
-
-                        $file = $this->registry->create(File::class, [$this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options]);
-                        $this->status_code = $file->status_code;
-
-                        if ($file->success) {
-                            if ($file->status_code === 304) {
-                                // Set raw_data to false here too, to signify that the cache
-                                // is still valid.
-                                $this->raw_data = false;
-                                $cache->set_data($cacheKey, $this->data, $this->cache_duration);
-                                return true;
-                            }
-                        } else {
-                            $this->check_modified = false;
-                            if ($this->force_cache_fallback) {
-                                $cache->set_data($cacheKey, $this->data, $this->cache_duration);
-                                return true;
-                            }
-
-                            unset($file);
-                        }
-                    }
-                }
-                // If the cache is still valid, just return true
-                else {
-                    $this->raw_data = false;
-                    return true;
-                }
-            }
-            // If the cache is empty
-            else {
-                $this->data = [];
-            }
-        }
-
-        // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
-        if (!isset($file)) {
-            if ($this->file instanceof \SimplePie\File && $this->file->url === $this->feed_url) {
-                $file =& $this->file;
-            } else {
-                $headers = [
-                    'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
-                ];
-                $file = $this->registry->create(File::class, [$this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options]);
-            }
-        }
-        $this->status_code = $file->status_code;
-
-        // If the file connection has an error, set SimplePie::error to that and quit
-        if (!$file->success && !($file->method & self::FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) {
-            $this->error = $file->error;
-            return !empty($this->data);
-        }
-
-        if (!$this->force_feed) {
-            // Check if the supplied URL is a feed, if it isn't, look for it.
-            $locate = $this->registry->create(Locator::class, [&$file, $this->timeout, $this->useragent, $this->max_checked_feeds, $this->force_fsockopen, $this->curl_options]);
-
-            if (!$locate->is_feed($file)) {
-                $copyStatusCode = $file->status_code;
-                $copyContentType = $file->headers['content-type'];
-                try {
-                    $microformats = false;
-                    if (class_exists('DOMXpath') && function_exists('Mf2\parse')) {
-                        $doc = new \DOMDocument();
-                        @$doc->loadHTML($file->body);
-                        $xpath = new \DOMXpath($doc);
-                        // Check for both h-feed and h-entry, as both a feed with no entries
-                        // and a list of entries without an h-feed wrapper are both valid.
-                        $query = '//*[contains(concat(" ", @class, " "), " h-feed ") or '.
-                            'contains(concat(" ", @class, " "), " h-entry ")]';
-                        $result = $xpath->query($query);
-                        $microformats = $result->length !== 0;
-                    }
-                    // Now also do feed discovery, but if microformats were found don't
-                    // overwrite the current value of file.
-                    $discovered = $locate->find(
-                        $this->autodiscovery,
-                        $this->all_discovered_feeds
-                    );
-                    if ($microformats) {
-                        if ($hub = $locate->get_rel_link('hub')) {
-                            $self = $locate->get_rel_link('self');
-                            $this->store_links($file, $hub, $self);
-                        }
-                        // Push the current file onto all_discovered feeds so the user can
-                        // be shown this as one of the options.
-                        if (isset($this->all_discovered_feeds)) {
-                            $this->all_discovered_feeds[] = $file;
-                        }
-                    } else {
-                        if ($discovered) {
-                            $file = $discovered;
-                        } else {
-                            // We need to unset this so that if SimplePie::set_file() has
-                            // been called that object is untouched
-                            unset($file);
-                            $this->error = "A feed could not be found at `$this->feed_url`; the status code is `$copyStatusCode` and content-type is `$copyContentType`";
-                            $this->registry->call(Misc::class, 'error', [$this->error, E_USER_NOTICE, __FILE__, __LINE__]);
-                            return false;
-                        }
-                    }
-                } catch (\SimplePie\Exception $e) {
-                    // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
-                    unset($file);
-                    // This is usually because DOMDocument doesn't exist
-                    $this->error = $e->getMessage();
-                    $this->registry->call(Misc::class, 'error', [$this->error, E_USER_NOTICE, $e->getFile(), $e->getLine()]);
-                    return false;
-                }
-
-                if ($cache) {
-                    $this->data = [
-                        'url' => $this->feed_url,
-                        'feed_url' => $file->url,
-                        'build' => \SimplePie\Misc::get_build(),
-                        'cache_expiration_time' => $this->cache_duration + time(),
-                    ];
-
-                    if (!$cache->set_data($cacheKey, $this->data, $this->cache_duration)) {
-                        trigger_error("$this->cache_location is not writable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
-                    }
-                }
-            }
-            $this->feed_url = $file->url;
-            $locate = null;
-        }
-
-        $this->raw_data = $file->body;
-        $this->permanent_url = $file->permanent_url;
-        $headers = $file->headers;
-        $sniffer = $this->registry->create(Sniffer::class, [&$file]);
-        $sniffed = $sniffer->get_type();
-
-        return [$headers, $sniffed];
-    }
-
-    /**
-     * Get the error message for the occurred error
-     *
-     * @return string|array Error message, or array of messages for multifeeds
-     */
-    public function error()
-    {
-        return $this->error;
-    }
-
-    /**
-     * Get the last HTTP status code
-     *
-     * @return int Status code
-     */
-    public function status_code()
-    {
-        return $this->status_code;
-    }
-
-    /**
-     * Get the raw XML
-     *
-     * This is the same as the old `$feed->enable_xml_dump(true)`, but returns
-     * the data instead of printing it.
-     *
-     * @return string|boolean Raw XML data, false if the cache is used
-     */
-    public function get_raw_data()
-    {
-        return $this->raw_data;
-    }
-
-    /**
-     * Get the character encoding used for output
-     *
-     * @since Preview Release
-     * @return string
-     */
-    public function get_encoding()
-    {
-        return $this->sanitize->output_encoding;
-    }
-
-    /**
-     * Send the content-type header with correct encoding
-     *
-     * This method ensures that the SimplePie-enabled page is being served with
-     * the correct {@link http://www.iana.org/assignments/media-types/ mime-type}
-     * and character encoding HTTP headers (character encoding determined by the
-     * {@see set_output_encoding} config option).
-     *
-     * This won't work properly if any content or whitespace has already been
-     * sent to the browser, because it relies on PHP's
-     * {@link http://php.net/header header()} function, and these are the
-     * circumstances under which the function works.
-     *
-     * Because it's setting these settings for the entire page (as is the nature
-     * of HTTP headers), this should only be used once per page (again, at the
-     * top).
-     *
-     * @param string $mime MIME type to serve the page as
-     */
-    public function handle_content_type($mime = 'text/html')
-    {
-        if (!headers_sent()) {
-            $header = "Content-type: $mime;";
-            if ($this->get_encoding()) {
-                $header .= ' charset=' . $this->get_encoding();
-            } else {
-                $header .= ' charset=UTF-8';
-            }
-            header($header);
-        }
-    }
-
-    /**
-     * Get the type of the feed
-     *
-     * This returns a \SimplePie\SimplePie::TYPE_* constant, which can be tested against
-     * using {@link http://php.net/language.operators.bitwise bitwise operators}
-     *
-     * @since 0.8 (usage changed to using constants in 1.0)
-     * @see \SimplePie\SimplePie::TYPE_NONE Unknown.
-     * @see \SimplePie\SimplePie::TYPE_RSS_090 RSS 0.90.
-     * @see \SimplePie\SimplePie::TYPE_RSS_091_NETSCAPE RSS 0.91 (Netscape).
-     * @see \SimplePie\SimplePie::TYPE_RSS_091_USERLAND RSS 0.91 (Userland).
-     * @see \SimplePie\SimplePie::TYPE_RSS_091 RSS 0.91.
-     * @see \SimplePie\SimplePie::TYPE_RSS_092 RSS 0.92.
-     * @see \SimplePie\SimplePie::TYPE_RSS_093 RSS 0.93.
-     * @see \SimplePie\SimplePie::TYPE_RSS_094 RSS 0.94.
-     * @see \SimplePie\SimplePie::TYPE_RSS_10 RSS 1.0.
-     * @see \SimplePie\SimplePie::TYPE_RSS_20 RSS 2.0.x.
-     * @see \SimplePie\SimplePie::TYPE_RSS_RDF RDF-based RSS.
-     * @see \SimplePie\SimplePie::TYPE_RSS_SYNDICATION Non-RDF-based RSS (truly intended as syndication format).
-     * @see \SimplePie\SimplePie::TYPE_RSS_ALL Any version of RSS.
-     * @see \SimplePie\SimplePie::TYPE_ATOM_03 Atom 0.3.
-     * @see \SimplePie\SimplePie::TYPE_ATOM_10 Atom 1.0.
-     * @see \SimplePie\SimplePie::TYPE_ATOM_ALL Any version of Atom.
-     * @see \SimplePie\SimplePie::TYPE_ALL Any known/supported feed type.
-     * @return int \SimplePie\SimplePie::TYPE_* constant
-     */
-    public function get_type()
-    {
-        if (!isset($this->data['type'])) {
-            $this->data['type'] = self::TYPE_ALL;
-            if (isset($this->data['child'][self::NAMESPACE_ATOM_10]['feed'])) {
-                $this->data['type'] &= self::TYPE_ATOM_10;
-            } elseif (isset($this->data['child'][self::NAMESPACE_ATOM_03]['feed'])) {
-                $this->data['type'] &= self::TYPE_ATOM_03;
-            } elseif (isset($this->data['child'][self::NAMESPACE_RDF]['RDF'])) {
-                if (isset($this->data['child'][self::NAMESPACE_RDF]['RDF'][0]['child'][self::NAMESPACE_RSS_10]['channel'])
-                || isset($this->data['child'][self::NAMESPACE_RDF]['RDF'][0]['child'][self::NAMESPACE_RSS_10]['image'])
-                || isset($this->data['child'][self::NAMESPACE_RDF]['RDF'][0]['child'][self::NAMESPACE_RSS_10]['item'])
-                || isset($this->data['child'][self::NAMESPACE_RDF]['RDF'][0]['child'][self::NAMESPACE_RSS_10]['textinput'])) {
-                    $this->data['type'] &= self::TYPE_RSS_10;
-                }
-                if (isset($this->data['child'][self::NAMESPACE_RDF]['RDF'][0]['child'][self::NAMESPACE_RSS_090]['channel'])
-                || isset($this->data['child'][self::NAMESPACE_RDF]['RDF'][0]['child'][self::NAMESPACE_RSS_090]['image'])
-                || isset($this->data['child'][self::NAMESPACE_RDF]['RDF'][0]['child'][self::NAMESPACE_RSS_090]['item'])
-                || isset($this->data['child'][self::NAMESPACE_RDF]['RDF'][0]['child'][self::NAMESPACE_RSS_090]['textinput'])) {
-                    $this->data['type'] &= self::TYPE_RSS_090;
-                }
-            } elseif (isset($this->data['child'][self::NAMESPACE_RSS_20]['rss'])) {
-                $this->data['type'] &= self::TYPE_RSS_ALL;
-                if (isset($this->data['child'][self::NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version'])) {
-                    switch (trim($this->data['child'][self::NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version'])) {
-                        case '0.91':
-                            $this->data['type'] &= self::TYPE_RSS_091;
-                            if (isset($this->data['child'][self::NAMESPACE_RSS_20]['rss'][0]['child'][self::NAMESPACE_RSS_20]['skiphours']['hour'][0]['data'])) {
-                                switch (trim($this->data['child'][self::NAMESPACE_RSS_20]['rss'][0]['child'][self::NAMESPACE_RSS_20]['skiphours']['hour'][0]['data'])) {
-                                    case '0':
-                                        $this->data['type'] &= self::TYPE_RSS_091_NETSCAPE;
-                                        break;
-
-                                    case '24':
-                                        $this->data['type'] &= self::TYPE_RSS_091_USERLAND;
-                                        break;
-                                }
-                            }
-                            break;
-
-                        case '0.92':
-                            $this->data['type'] &= self::TYPE_RSS_092;
-                            break;
-
-                        case '0.93':
-                            $this->data['type'] &= self::TYPE_RSS_093;
-                            break;
-
-                        case '0.94':
-                            $this->data['type'] &= self::TYPE_RSS_094;
-                            break;
-
-                        case '2.0':
-                            $this->data['type'] &= self::TYPE_RSS_20;
-                            break;
-                    }
-                }
-            } else {
-                $this->data['type'] = self::TYPE_NONE;
-            }
-        }
-        return $this->data['type'];
-    }
-
-    /**
-     * Get the URL for the feed
-     *
-     * When the 'permanent' mode is enabled, returns the original feed URL,
-     * except in the case of an `HTTP 301 Moved Permanently` status response,
-     * in which case the location of the first redirection is returned.
-     *
-     * When the 'permanent' mode is disabled (default),
-     * may or may not be different from the URL passed to {@see set_feed_url()},
-     * depending on whether auto-discovery was used, and whether there were
-     * any redirects along the way.
-     *
-     * @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.)
-     * @todo Support <itunes:new-feed-url>
-     * @todo Also, |atom:link|@rel=self
-     * @param bool $permanent Permanent mode to return only the original URL or the first redirection
-     * iff it is a 301 redirection
-     * @return string|null
-     */
-    public function subscribe_url($permanent = false)
-    {
-        if ($permanent) {
-            if ($this->permanent_url !== null) {
-                // sanitize encodes ampersands which are required when used in a url.
-                return str_replace(
-                    '&amp;',
-                    '&',
-                    $this->sanitize(
-                        $this->permanent_url,
-                        self::CONSTRUCT_IRI
-                    )
-                );
-            }
-        } else {
-            if ($this->feed_url !== null) {
-                return str_replace(
-                    '&amp;',
-                    '&',
-                    $this->sanitize(
-                        $this->feed_url,
-                        self::CONSTRUCT_IRI
-                    )
-                );
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Get data for an feed-level element
-     *
-     * This method allows you to get access to ANY element/attribute that is a
-     * sub-element of the opening feed tag.
-     *
-     * The return value is an indexed array of elements matching the given
-     * namespace and tag name. Each element has `attribs`, `data` and `child`
-     * subkeys. For `attribs` and `child`, these contain namespace subkeys.
-     * `attribs` then has one level of associative name => value data (where
-     * `value` is a string) after the namespace. `child` has tag-indexed keys
-     * after the namespace, each member of which is an indexed array matching
-     * this same format.
-     *
-     * For example:
-     * <pre>
-     * // This is probably a bad example because we already support
-     * // <media:content> natively, but it shows you how to parse through
-     * // the nodes.
-     * $group = $item->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'group');
-     * $content = $group[0]['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['content'];
-     * $file = $content[0]['attribs']['']['url'];
-     * echo $file;
-     * </pre>
-     *
-     * @since 1.0
-     * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
-     * @param string $namespace The URL of the XML namespace of the elements you're trying to access
-     * @param string $tag Tag name
-     * @return array
-     */
-    public function get_feed_tags($namespace, $tag)
-    {
-        $type = $this->get_type();
-        if ($type & self::TYPE_ATOM_10) {
-            if (isset($this->data['child'][self::NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag])) {
-                return $this->data['child'][self::NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
-            }
-        }
-        if ($type & self::TYPE_ATOM_03) {
-            if (isset($this->data['child'][self::NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag])) {
-                return $this->data['child'][self::NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
-            }
-        }
-        if ($type & self::TYPE_RSS_RDF) {
-            if (isset($this->data['child'][self::NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag])) {
-                return $this->data['child'][self::NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
-            }
-        }
-        if ($type & self::TYPE_RSS_SYNDICATION) {
-            if (isset($this->data['child'][self::NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag])) {
-                return $this->data['child'][self::NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Get data for an channel-level element
-     *
-     * This method allows you to get access to ANY element/attribute in the
-     * channel/header section of the feed.
-     *
-     * See {@see SimplePie::get_feed_tags()} for a description of the return value
-     *
-     * @since 1.0
-     * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
-     * @param string $namespace The URL of the XML namespace of the elements you're trying to access
-     * @param string $tag Tag name
-     * @return array
-     */
-    public function get_channel_tags($namespace, $tag)
-    {
-        $type = $this->get_type();
-        if ($type & self::TYPE_ATOM_ALL) {
-            if ($return = $this->get_feed_tags($namespace, $tag)) {
-                return $return;
-            }
-        }
-        if ($type & self::TYPE_RSS_10) {
-            if ($channel = $this->get_feed_tags(self::NAMESPACE_RSS_10, 'channel')) {
-                if (isset($channel[0]['child'][$namespace][$tag])) {
-                    return $channel[0]['child'][$namespace][$tag];
-                }
-            }
-        }
-        if ($type & self::TYPE_RSS_090) {
-            if ($channel = $this->get_feed_tags(self::NAMESPACE_RSS_090, 'channel')) {
-                if (isset($channel[0]['child'][$namespace][$tag])) {
-                    return $channel[0]['child'][$namespace][$tag];
-                }
-            }
-        }
-        if ($type & self::TYPE_RSS_SYNDICATION) {
-            if ($channel = $this->get_feed_tags(self::NAMESPACE_RSS_20, 'channel')) {
-                if (isset($channel[0]['child'][$namespace][$tag])) {
-                    return $channel[0]['child'][$namespace][$tag];
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Get data for an channel-level element
-     *
-     * This method allows you to get access to ANY element/attribute in the
-     * image/logo section of the feed.
-     *
-     * See {@see SimplePie::get_feed_tags()} for a description of the return value
-     *
-     * @since 1.0
-     * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
-     * @param string $namespace The URL of the XML namespace of the elements you're trying to access
-     * @param string $tag Tag name
-     * @return array
-     */
-    public function get_image_tags($namespace, $tag)
-    {
-        $type = $this->get_type();
-        if ($type & self::TYPE_RSS_10) {
-            if ($image = $this->get_feed_tags(self::NAMESPACE_RSS_10, 'image')) {
-                if (isset($image[0]['child'][$namespace][$tag])) {
-                    return $image[0]['child'][$namespace][$tag];
-                }
-            }
-        }
-        if ($type & self::TYPE_RSS_090) {
-            if ($image = $this->get_feed_tags(self::NAMESPACE_RSS_090, 'image')) {
-                if (isset($image[0]['child'][$namespace][$tag])) {
-                    return $image[0]['child'][$namespace][$tag];
-                }
-            }
-        }
-        if ($type & self::TYPE_RSS_SYNDICATION) {
-            if ($image = $this->get_channel_tags(self::NAMESPACE_RSS_20, 'image')) {
-                if (isset($image[0]['child'][$namespace][$tag])) {
-                    return $image[0]['child'][$namespace][$tag];
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Get the base URL value from the feed
-     *
-     * Uses `<xml:base>` if available, otherwise uses the first link in the
-     * feed, or failing that, the URL of the feed itself.
-     *
-     * @see get_link
-     * @see subscribe_url
-     *
-     * @param array $element
-     * @return string
-     */
-    public function get_base($element = [])
-    {
-        if (!empty($element['xml_base_explicit']) && isset($element['xml_base'])) {
-            return $element['xml_base'];
-        } elseif ($this->get_link() !== null) {
-            return $this->get_link();
-        }
-
-        return $this->subscribe_url();
-    }
-
-    /**
-     * Sanitize feed data
-     *
-     * @access private
-     * @see \SimplePie\Sanitize::sanitize()
-     * @param string $data Data to sanitize
-     * @param int $type One of the \SimplePie\SimplePie::CONSTRUCT_* constants
-     * @param string $base Base URL to resolve URLs against
-     * @return string Sanitized data
-     */
-    public function sanitize($data, $type, $base = '')
-    {
-        try {
-            return $this->sanitize->sanitize($data, $type, $base);
-        } catch (\SimplePie\Exception $e) {
-            if (!$this->enable_exceptions) {
-                $this->error = $e->getMessage();
-                $this->registry->call(Misc::class, 'error', [$this->error, E_USER_WARNING, $e->getFile(), $e->getLine()]);
-                return '';
-            }
-
-            throw $e;
-        }
-    }
-
-    /**
-     * Get the title of the feed
-     *
-     * Uses `<atom:title>`, `<title>` or `<dc:title>`
-     *
-     * @since 1.0 (previously called `get_feed_title` since 0.8)
-     * @return string|null
-     */
-    public function get_title()
-    {
-        if ($return = $this->get_channel_tags(self::NAMESPACE_ATOM_10, 'title')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_10_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_ATOM_03, 'title')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_03_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_RSS_10, 'title')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_RSS_090, 'title')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_RSS_20, 'title')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_DC_11, 'title')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_DC_10, 'title')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a category for the feed
-     *
-     * @since Unknown
-     * @param int $key The category that you want to return. Remember that arrays begin with 0, not 1
-     * @return \SimplePie\Category|null
-     */
-    public function get_category($key = 0)
-    {
-        $categories = $this->get_categories();
-        if (isset($categories[$key])) {
-            return $categories[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all categories for the feed
-     *
-     * Uses `<atom:category>`, `<category>` or `<dc:subject>`
-     *
-     * @since Unknown
-     * @return array|null List of {@see \SimplePie\Category} objects
-     */
-    public function get_categories()
-    {
-        $categories = [];
-
-        foreach ((array) $this->get_channel_tags(self::NAMESPACE_ATOM_10, 'category') as $category) {
-            $term = null;
-            $scheme = null;
-            $label = null;
-            if (isset($category['attribs']['']['term'])) {
-                $term = $this->sanitize($category['attribs']['']['term'], self::CONSTRUCT_TEXT);
-            }
-            if (isset($category['attribs']['']['scheme'])) {
-                $scheme = $this->sanitize($category['attribs']['']['scheme'], self::CONSTRUCT_TEXT);
-            }
-            if (isset($category['attribs']['']['label'])) {
-                $label = $this->sanitize($category['attribs']['']['label'], self::CONSTRUCT_TEXT);
-            }
-            $categories[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
-        }
-        foreach ((array) $this->get_channel_tags(self::NAMESPACE_RSS_20, 'category') as $category) {
-            // This is really the label, but keep this as the term also for BC.
-            // Label will also work on retrieving because that falls back to term.
-            $term = $this->sanitize($category['data'], self::CONSTRUCT_TEXT);
-            if (isset($category['attribs']['']['domain'])) {
-                $scheme = $this->sanitize($category['attribs']['']['domain'], self::CONSTRUCT_TEXT);
-            } else {
-                $scheme = null;
-            }
-            $categories[] = $this->registry->create(Category::class, [$term, $scheme, null]);
-        }
-        foreach ((array) $this->get_channel_tags(self::NAMESPACE_DC_11, 'subject') as $category) {
-            $categories[] = $this->registry->create(Category::class, [$this->sanitize($category['data'], self::CONSTRUCT_TEXT), null, null]);
-        }
-        foreach ((array) $this->get_channel_tags(self::NAMESPACE_DC_10, 'subject') as $category) {
-            $categories[] = $this->registry->create(Category::class, [$this->sanitize($category['data'], self::CONSTRUCT_TEXT), null, null]);
-        }
-
-        if (!empty($categories)) {
-            return array_unique($categories);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get an author for the feed
-     *
-     * @since 1.1
-     * @param int $key The author that you want to return. Remember that arrays begin with 0, not 1
-     * @return \SimplePie\Author|null
-     */
-    public function get_author($key = 0)
-    {
-        $authors = $this->get_authors();
-        if (isset($authors[$key])) {
-            return $authors[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all authors for the feed
-     *
-     * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>`
-     *
-     * @since 1.1
-     * @return array|null List of {@see \SimplePie\Author} objects
-     */
-    public function get_authors()
-    {
-        $authors = [];
-        foreach ((array) $this->get_channel_tags(self::NAMESPACE_ATOM_10, 'author') as $author) {
-            $name = null;
-            $uri = null;
-            $email = null;
-            if (isset($author['child'][self::NAMESPACE_ATOM_10]['name'][0]['data'])) {
-                $name = $this->sanitize($author['child'][self::NAMESPACE_ATOM_10]['name'][0]['data'], self::CONSTRUCT_TEXT);
-            }
-            if (isset($author['child'][self::NAMESPACE_ATOM_10]['uri'][0]['data'])) {
-                $uri = $this->sanitize($author['child'][self::NAMESPACE_ATOM_10]['uri'][0]['data'], self::CONSTRUCT_IRI, $this->get_base($author['child'][self::NAMESPACE_ATOM_10]['uri'][0]));
-            }
-            if (isset($author['child'][self::NAMESPACE_ATOM_10]['email'][0]['data'])) {
-                $email = $this->sanitize($author['child'][self::NAMESPACE_ATOM_10]['email'][0]['data'], self::CONSTRUCT_TEXT);
-            }
-            if ($name !== null || $email !== null || $uri !== null) {
-                $authors[] = $this->registry->create(Author::class, [$name, $uri, $email]);
-            }
-        }
-        if ($author = $this->get_channel_tags(self::NAMESPACE_ATOM_03, 'author')) {
-            $name = null;
-            $url = null;
-            $email = null;
-            if (isset($author[0]['child'][self::NAMESPACE_ATOM_03]['name'][0]['data'])) {
-                $name = $this->sanitize($author[0]['child'][self::NAMESPACE_ATOM_03]['name'][0]['data'], self::CONSTRUCT_TEXT);
-            }
-            if (isset($author[0]['child'][self::NAMESPACE_ATOM_03]['url'][0]['data'])) {
-                $url = $this->sanitize($author[0]['child'][self::NAMESPACE_ATOM_03]['url'][0]['data'], self::CONSTRUCT_IRI, $this->get_base($author[0]['child'][self::NAMESPACE_ATOM_03]['url'][0]));
-            }
-            if (isset($author[0]['child'][self::NAMESPACE_ATOM_03]['email'][0]['data'])) {
-                $email = $this->sanitize($author[0]['child'][self::NAMESPACE_ATOM_03]['email'][0]['data'], self::CONSTRUCT_TEXT);
-            }
-            if ($name !== null || $email !== null || $url !== null) {
-                $authors[] = $this->registry->create(Author::class, [$name, $url, $email]);
-            }
-        }
-        foreach ((array) $this->get_channel_tags(self::NAMESPACE_DC_11, 'creator') as $author) {
-            $authors[] = $this->registry->create(Author::class, [$this->sanitize($author['data'], self::CONSTRUCT_TEXT), null, null]);
-        }
-        foreach ((array) $this->get_channel_tags(self::NAMESPACE_DC_10, 'creator') as $author) {
-            $authors[] = $this->registry->create(Author::class, [$this->sanitize($author['data'], self::CONSTRUCT_TEXT), null, null]);
-        }
-        foreach ((array) $this->get_channel_tags(self::NAMESPACE_ITUNES, 'author') as $author) {
-            $authors[] = $this->registry->create(Author::class, [$this->sanitize($author['data'], self::CONSTRUCT_TEXT), null, null]);
-        }
-
-        if (!empty($authors)) {
-            return array_unique($authors);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a contributor for the feed
-     *
-     * @since 1.1
-     * @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1
-     * @return \SimplePie\Author|null
-     */
-    public function get_contributor($key = 0)
-    {
-        $contributors = $this->get_contributors();
-        if (isset($contributors[$key])) {
-            return $contributors[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all contributors for the feed
-     *
-     * Uses `<atom:contributor>`
-     *
-     * @since 1.1
-     * @return array|null List of {@see \SimplePie\Author} objects
-     */
-    public function get_contributors()
-    {
-        $contributors = [];
-        foreach ((array) $this->get_channel_tags(self::NAMESPACE_ATOM_10, 'contributor') as $contributor) {
-            $name = null;
-            $uri = null;
-            $email = null;
-            if (isset($contributor['child'][self::NAMESPACE_ATOM_10]['name'][0]['data'])) {
-                $name = $this->sanitize($contributor['child'][self::NAMESPACE_ATOM_10]['name'][0]['data'], self::CONSTRUCT_TEXT);
-            }
-            if (isset($contributor['child'][self::NAMESPACE_ATOM_10]['uri'][0]['data'])) {
-                $uri = $this->sanitize($contributor['child'][self::NAMESPACE_ATOM_10]['uri'][0]['data'], self::CONSTRUCT_IRI, $this->get_base($contributor['child'][self::NAMESPACE_ATOM_10]['uri'][0]));
-            }
-            if (isset($contributor['child'][self::NAMESPACE_ATOM_10]['email'][0]['data'])) {
-                $email = $this->sanitize($contributor['child'][self::NAMESPACE_ATOM_10]['email'][0]['data'], self::CONSTRUCT_TEXT);
-            }
-            if ($name !== null || $email !== null || $uri !== null) {
-                $contributors[] = $this->registry->create(Author::class, [$name, $uri, $email]);
-            }
-        }
-        foreach ((array) $this->get_channel_tags(self::NAMESPACE_ATOM_03, 'contributor') as $contributor) {
-            $name = null;
-            $url = null;
-            $email = null;
-            if (isset($contributor['child'][self::NAMESPACE_ATOM_03]['name'][0]['data'])) {
-                $name = $this->sanitize($contributor['child'][self::NAMESPACE_ATOM_03]['name'][0]['data'], self::CONSTRUCT_TEXT);
-            }
-            if (isset($contributor['child'][self::NAMESPACE_ATOM_03]['url'][0]['data'])) {
-                $url = $this->sanitize($contributor['child'][self::NAMESPACE_ATOM_03]['url'][0]['data'], self::CONSTRUCT_IRI, $this->get_base($contributor['child'][self::NAMESPACE_ATOM_03]['url'][0]));
-            }
-            if (isset($contributor['child'][self::NAMESPACE_ATOM_03]['email'][0]['data'])) {
-                $email = $this->sanitize($contributor['child'][self::NAMESPACE_ATOM_03]['email'][0]['data'], self::CONSTRUCT_TEXT);
-            }
-            if ($name !== null || $email !== null || $url !== null) {
-                $contributors[] = $this->registry->create(Author::class, [$name, $url, $email]);
-            }
-        }
-
-        if (!empty($contributors)) {
-            return array_unique($contributors);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a single link for the feed
-     *
-     * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
-     * @param int $key The link that you want to return. Remember that arrays begin with 0, not 1
-     * @param string $rel The relationship of the link to return
-     * @return string|null Link URL
-     */
-    public function get_link($key = 0, $rel = 'alternate')
-    {
-        $links = $this->get_links($rel);
-        if (isset($links[$key])) {
-            return $links[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the permalink for the item
-     *
-     * Returns the first link available with a relationship of "alternate".
-     * Identical to {@see get_link()} with key 0
-     *
-     * @see get_link
-     * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
-     * @internal Added for parity between the parent-level and the item/entry-level.
-     * @return string|null Link URL
-     */
-    public function get_permalink()
-    {
-        return $this->get_link(0);
-    }
-
-    /**
-     * Get all links for the feed
-     *
-     * Uses `<atom:link>` or `<link>`
-     *
-     * @since Beta 2
-     * @param string $rel The relationship of links to return
-     * @return array|null Links found for the feed (strings)
-     */
-    public function get_links($rel = 'alternate')
-    {
-        if (!isset($this->data['links'])) {
-            $this->data['links'] = [];
-            if ($links = $this->get_channel_tags(self::NAMESPACE_ATOM_10, 'link')) {
-                foreach ($links as $link) {
-                    if (isset($link['attribs']['']['href'])) {
-                        $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
-                        $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], self::CONSTRUCT_IRI, $this->get_base($link));
-                    }
-                }
-            }
-            if ($links = $this->get_channel_tags(self::NAMESPACE_ATOM_03, 'link')) {
-                foreach ($links as $link) {
-                    if (isset($link['attribs']['']['href'])) {
-                        $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
-                        $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], self::CONSTRUCT_IRI, $this->get_base($link));
-                    }
-                }
-            }
-            if ($links = $this->get_channel_tags(self::NAMESPACE_RSS_10, 'link')) {
-                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], self::CONSTRUCT_IRI, $this->get_base($links[0]));
-            }
-            if ($links = $this->get_channel_tags(self::NAMESPACE_RSS_090, 'link')) {
-                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], self::CONSTRUCT_IRI, $this->get_base($links[0]));
-            }
-            if ($links = $this->get_channel_tags(self::NAMESPACE_RSS_20, 'link')) {
-                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], self::CONSTRUCT_IRI, $this->get_base($links[0]));
-            }
-
-            $keys = array_keys($this->data['links']);
-            foreach ($keys as $key) {
-                if ($this->registry->call(Misc::class, 'is_isegment_nz_nc', [$key])) {
-                    if (isset($this->data['links'][self::IANA_LINK_RELATIONS_REGISTRY . $key])) {
-                        $this->data['links'][self::IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][self::IANA_LINK_RELATIONS_REGISTRY . $key]);
-                        $this->data['links'][$key] =& $this->data['links'][self::IANA_LINK_RELATIONS_REGISTRY . $key];
-                    } else {
-                        $this->data['links'][self::IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
-                    }
-                } elseif (substr($key, 0, 41) === self::IANA_LINK_RELATIONS_REGISTRY) {
-                    $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
-                }
-                $this->data['links'][$key] = array_unique($this->data['links'][$key]);
-            }
-        }
-
-        if (isset($this->data['headers']['link'])) {
-            $link_headers = $this->data['headers']['link'];
-            if (is_array($link_headers)) {
-                $link_headers = implode(',', $link_headers);
-            }
-            // https://datatracker.ietf.org/doc/html/rfc8288
-            if (is_string($link_headers) &&
-                preg_match_all('/<(?P<uri>[^>]+)>\s*;\s*rel\s*=\s*(?P<quote>"?)' . preg_quote($rel) . '(?P=quote)\s*(?=,|$)/i', $link_headers, $matches)) {
-                return $matches['uri'];
-            }
-        }
-
-        if (isset($this->data['links'][$rel])) {
-            return $this->data['links'][$rel];
-        }
-
-        return null;
-    }
-
-    public function get_all_discovered_feeds()
-    {
-        return $this->all_discovered_feeds;
-    }
-
-    /**
-     * Get the content for the item
-     *
-     * Uses `<atom:subtitle>`, `<atom:tagline>`, `<description>`,
-     * `<dc:description>`, `<itunes:summary>` or `<itunes:subtitle>`
-     *
-     * @since 1.0 (previously called `get_feed_description()` since 0.8)
-     * @return string|null
-     */
-    public function get_description()
-    {
-        if ($return = $this->get_channel_tags(self::NAMESPACE_ATOM_10, 'subtitle')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_10_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_ATOM_03, 'tagline')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_03_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_RSS_10, 'description')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_RSS_090, 'description')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_RSS_20, 'description')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_DC_11, 'description')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_DC_10, 'description')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_ITUNES, 'summary')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_ITUNES, 'subtitle')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_HTML, $this->get_base($return[0]));
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the copyright info for the feed
-     *
-     * Uses `<atom:rights>`, `<atom:copyright>` or `<dc:rights>`
-     *
-     * @since 1.0 (previously called `get_feed_copyright()` since 0.8)
-     * @return string|null
-     */
-    public function get_copyright()
-    {
-        if ($return = $this->get_channel_tags(self::NAMESPACE_ATOM_10, 'rights')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_10_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_ATOM_03, 'copyright')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_03_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_RSS_20, 'copyright')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_DC_11, 'rights')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_DC_10, 'rights')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the language for the feed
-     *
-     * Uses `<language>`, `<dc:language>`, or @xml_lang
-     *
-     * @since 1.0 (previously called `get_feed_language()` since 0.8)
-     * @return string|null
-     */
-    public function get_language()
-    {
-        if ($return = $this->get_channel_tags(self::NAMESPACE_RSS_20, 'language')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_DC_11, 'language')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_DC_10, 'language')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        } elseif (isset($this->data['child'][self::NAMESPACE_ATOM_10]['feed'][0]['xml_lang'])) {
-            return $this->sanitize($this->data['child'][self::NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], self::CONSTRUCT_TEXT);
-        } elseif (isset($this->data['child'][self::NAMESPACE_ATOM_03]['feed'][0]['xml_lang'])) {
-            return $this->sanitize($this->data['child'][self::NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], self::CONSTRUCT_TEXT);
-        } elseif (isset($this->data['child'][self::NAMESPACE_RDF]['RDF'][0]['xml_lang'])) {
-            return $this->sanitize($this->data['child'][self::NAMESPACE_RDF]['RDF'][0]['xml_lang'], self::CONSTRUCT_TEXT);
-        } elseif (isset($this->data['headers']['content-language'])) {
-            return $this->sanitize($this->data['headers']['content-language'], self::CONSTRUCT_TEXT);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the latitude coordinates for the item
-     *
-     * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
-     *
-     * Uses `<geo:lat>` or `<georss:point>`
-     *
-     * @since 1.0
-     * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
-     * @link http://www.georss.org/ GeoRSS
-     * @return string|null
-     */
-    public function get_latitude()
-    {
-        if ($return = $this->get_channel_tags(self::NAMESPACE_W3C_BASIC_GEO, 'lat')) {
-            return (float) $return[0]['data'];
-        } elseif (($return = $this->get_channel_tags(self::NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) {
-            return (float) $match[1];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the longitude coordinates for the feed
-     *
-     * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
-     *
-     * Uses `<geo:long>`, `<geo:lon>` or `<georss:point>`
-     *
-     * @since 1.0
-     * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
-     * @link http://www.georss.org/ GeoRSS
-     * @return string|null
-     */
-    public function get_longitude()
-    {
-        if ($return = $this->get_channel_tags(self::NAMESPACE_W3C_BASIC_GEO, 'long')) {
-            return (float) $return[0]['data'];
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_W3C_BASIC_GEO, 'lon')) {
-            return (float) $return[0]['data'];
-        } elseif (($return = $this->get_channel_tags(self::NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) {
-            return (float) $match[2];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the feed logo's title
-     *
-     * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" title.
-     *
-     * Uses `<image><title>` or `<image><dc:title>`
-     *
-     * @return string|null
-     */
-    public function get_image_title()
-    {
-        if ($return = $this->get_image_tags(self::NAMESPACE_RSS_10, 'title')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_image_tags(self::NAMESPACE_RSS_090, 'title')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_image_tags(self::NAMESPACE_RSS_20, 'title')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_image_tags(self::NAMESPACE_DC_11, 'title')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_image_tags(self::NAMESPACE_DC_10, 'title')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_TEXT);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the feed logo's URL
-     *
-     * RSS 0.9.0, 2.0, Atom 1.0, and feeds with iTunes RSS tags are allowed to
-     * have a "feed logo" URL. This points directly to the image itself.
-     *
-     * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`,
-     * `<image><title>` or `<image><dc:title>`
-     *
-     * @return string|null
-     */
-    public function get_image_url()
-    {
-        if ($return = $this->get_channel_tags(self::NAMESPACE_ITUNES, 'image')) {
-            return $this->sanitize($return[0]['attribs']['']['href'], self::CONSTRUCT_IRI);
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_ATOM_10, 'logo')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_IRI, $this->get_base($return[0]));
-        } elseif ($return = $this->get_channel_tags(self::NAMESPACE_ATOM_10, 'icon')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_IRI, $this->get_base($return[0]));
-        } elseif ($return = $this->get_image_tags(self::NAMESPACE_RSS_10, 'url')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_IRI, $this->get_base($return[0]));
-        } elseif ($return = $this->get_image_tags(self::NAMESPACE_RSS_090, 'url')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_IRI, $this->get_base($return[0]));
-        } elseif ($return = $this->get_image_tags(self::NAMESPACE_RSS_20, 'url')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_IRI, $this->get_base($return[0]));
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the feed logo's link
-     *
-     * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" link. This
-     * points to a human-readable page that the image should link to.
-     *
-     * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`,
-     * `<image><title>` or `<image><dc:title>`
-     *
-     * @return string|null
-     */
-    public function get_image_link()
-    {
-        if ($return = $this->get_image_tags(self::NAMESPACE_RSS_10, 'link')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_IRI, $this->get_base($return[0]));
-        } elseif ($return = $this->get_image_tags(self::NAMESPACE_RSS_090, 'link')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_IRI, $this->get_base($return[0]));
-        } elseif ($return = $this->get_image_tags(self::NAMESPACE_RSS_20, 'link')) {
-            return $this->sanitize($return[0]['data'], self::CONSTRUCT_IRI, $this->get_base($return[0]));
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the feed logo's link
-     *
-     * RSS 2.0 feeds are allowed to have a "feed logo" width.
-     *
-     * Uses `<image><width>` or defaults to 88 if no width is specified and
-     * the feed is an RSS 2.0 feed.
-     *
-     * @return int|null
-     */
-    public function get_image_width()
-    {
-        if ($return = $this->get_image_tags(self::NAMESPACE_RSS_20, 'width')) {
-            return intval($return[0]['data']);
-        } elseif ($this->get_type() & self::TYPE_RSS_SYNDICATION && $this->get_image_tags(self::NAMESPACE_RSS_20, 'url')) {
-            return 88;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the feed logo's height
-     *
-     * RSS 2.0 feeds are allowed to have a "feed logo" height.
-     *
-     * Uses `<image><height>` or defaults to 31 if no height is specified and
-     * the feed is an RSS 2.0 feed.
-     *
-     * @return int|null
-     */
-    public function get_image_height()
-    {
-        if ($return = $this->get_image_tags(self::NAMESPACE_RSS_20, 'height')) {
-            return intval($return[0]['data']);
-        } elseif ($this->get_type() & self::TYPE_RSS_SYNDICATION && $this->get_image_tags(self::NAMESPACE_RSS_20, 'url')) {
-            return 31;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the number of items in the feed
-     *
-     * This is well-suited for {@link http://php.net/for for()} loops with
-     * {@see get_item()}
-     *
-     * @param int $max Maximum value to return. 0 for no limit
-     * @return int Number of items in the feed
-     */
-    public function get_item_quantity($max = 0)
-    {
-        $max = (int) $max;
-        $qty = count($this->get_items());
-        if ($max === 0) {
-            return $qty;
-        }
-
-        return ($qty > $max) ? $max : $qty;
-    }
-
-    /**
-     * Get a single item from the feed
-     *
-     * This is better suited for {@link http://php.net/for for()} loops, whereas
-     * {@see get_items()} is better suited for
-     * {@link http://php.net/foreach foreach()} loops.
-     *
-     * @see get_item_quantity()
-     * @since Beta 2
-     * @param int $key The item that you want to return. Remember that arrays begin with 0, not 1
-     * @return \SimplePie\Item|null
-     */
-    public function get_item($key = 0)
-    {
-        $items = $this->get_items();
-        if (isset($items[$key])) {
-            return $items[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all items from the feed
-     *
-     * This is better suited for {@link http://php.net/for for()} loops, whereas
-     * {@see get_items()} is better suited for
-     * {@link http://php.net/foreach foreach()} loops.
-     *
-     * @see get_item_quantity
-     * @since Beta 2
-     * @param int $start Index to start at
-     * @param int $end Number of items to return. 0 for all items after `$start`
-     * @return \SimplePie\Item[]|null List of {@see \SimplePie\Item} objects
-     */
-    public function get_items($start = 0, $end = 0)
-    {
-        if (!isset($this->data['items'])) {
-            if (!empty($this->multifeed_objects)) {
-                $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
-                if (empty($this->data['items'])) {
-                    return [];
-                }
-                return $this->data['items'];
-            }
-            $this->data['items'] = [];
-            if ($items = $this->get_feed_tags(self::NAMESPACE_ATOM_10, 'entry')) {
-                $keys = array_keys($items);
-                foreach ($keys as $key) {
-                    $this->data['items'][] = $this->registry->create(Item::class, [$this, $items[$key]]);
-                }
-            }
-            if ($items = $this->get_feed_tags(self::NAMESPACE_ATOM_03, 'entry')) {
-                $keys = array_keys($items);
-                foreach ($keys as $key) {
-                    $this->data['items'][] = $this->registry->create(Item::class, [$this, $items[$key]]);
-                }
-            }
-            if ($items = $this->get_feed_tags(self::NAMESPACE_RSS_10, 'item')) {
-                $keys = array_keys($items);
-                foreach ($keys as $key) {
-                    $this->data['items'][] = $this->registry->create(Item::class, [$this, $items[$key]]);
-                }
-            }
-            if ($items = $this->get_feed_tags(self::NAMESPACE_RSS_090, 'item')) {
-                $keys = array_keys($items);
-                foreach ($keys as $key) {
-                    $this->data['items'][] = $this->registry->create(Item::class, [$this, $items[$key]]);
-                }
-            }
-            if ($items = $this->get_channel_tags(self::NAMESPACE_RSS_20, 'item')) {
-                $keys = array_keys($items);
-                foreach ($keys as $key) {
-                    $this->data['items'][] = $this->registry->create(Item::class, [$this, $items[$key]]);
-                }
-            }
-        }
-
-        if (empty($this->data['items'])) {
-            return [];
-        }
-
-        if ($this->order_by_date) {
-            if (!isset($this->data['ordered_items'])) {
-                $this->data['ordered_items'] = $this->data['items'];
-                usort($this->data['ordered_items'], [get_class($this), 'sort_items']);
-            }
-            $items = $this->data['ordered_items'];
-        } else {
-            $items = $this->data['items'];
-        }
-        // Slice the data as desired
-        if ($end === 0) {
-            return array_slice($items, $start);
-        }
-
-        return array_slice($items, $start, $end);
-    }
-
-    /**
-     * Set the favicon handler
-     *
-     * @deprecated Use your own favicon handling instead
-     */
-    public function set_favicon_handler($page = false, $qs = 'i')
-    {
-        trigger_error('Favicon handling has been removed, please use your own handling', \E_USER_DEPRECATED);
-        return false;
-    }
-
-    /**
-     * Get the favicon for the current feed
-     *
-     * @deprecated Use your own favicon handling instead
-     */
-    public function get_favicon()
-    {
-        trigger_error('Favicon handling has been removed, please use your own handling', \E_USER_DEPRECATED);
-
-        if (($url = $this->get_link()) !== null) {
-            return 'https://www.google.com/s2/favicons?domain=' . urlencode($url);
-        }
-
-        return false;
-    }
-
-    /**
-     * Magic method handler
-     *
-     * @param string $method Method name
-     * @param array $args Arguments to the method
-     * @return mixed
-     */
-    public function __call($method, $args)
-    {
-        if (strpos($method, 'subscribe_') === 0) {
-            trigger_error('subscribe_*() has been deprecated, implement the callback yourself', \E_USER_DEPRECATED);
-            return '';
-        }
-        if ($method === 'enable_xml_dump') {
-            trigger_error('enable_xml_dump() has been deprecated, use get_raw_data() instead', \E_USER_DEPRECATED);
-            return false;
-        }
-
-        $class = get_class($this);
-        $trace = debug_backtrace();
-        $file = $trace[0]['file'];
-        $line = $trace[0]['line'];
-        trigger_error("Call to undefined method $class::$method() in $file on line $line", E_USER_ERROR);
-    }
-
-    /**
-     * Sorting callback for items
-     *
-     * @access private
-     * @param SimplePie $a
-     * @param SimplePie $b
-     * @return boolean
-     */
-    public static function sort_items($a, $b)
-    {
-        $a_date = $a->get_date('U');
-        $b_date = $b->get_date('U');
-        if ($a_date && $b_date) {
-            return $a_date > $b_date ? -1 : 1;
-        }
-        // Sort items without dates to the top.
-        if ($a_date) {
-            return 1;
-        }
-        if ($b_date) {
-            return -1;
-        }
-        return 0;
-    }
-
-    /**
-     * Merge items from several feeds into one
-     *
-     * If you're merging multiple feeds together, they need to all have dates
-     * for the items or else SimplePie will refuse to sort them.
-     *
-     * @link http://simplepie.org/wiki/tutorial/sort_multiple_feeds_by_time_and_date#if_feeds_require_separate_per-feed_settings
-     * @param array $urls List of SimplePie feed objects to merge
-     * @param int $start Starting item
-     * @param int $end Number of items to return
-     * @param int $limit Maximum number of items per feed
-     * @return array
-     */
-    public static function merge_items($urls, $start = 0, $end = 0, $limit = 0)
-    {
-        if (is_array($urls) && sizeof($urls) > 0) {
-            $items = [];
-            foreach ($urls as $arg) {
-                if ($arg instanceof SimplePie) {
-                    $items = array_merge($items, $arg->get_items(0, $limit));
-                } else {
-                    trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
-                }
-            }
-
-            usort($items, [get_class($urls[0]), 'sort_items']);
-
-            if ($end === 0) {
-                return array_slice($items, $start);
-            }
-
-            return array_slice($items, $start, $end);
-        }
-
-        trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
-        return [];
-    }
-
-    /**
-     * Store PubSubHubbub links as headers
-     *
-     * There is no way to find PuSH links in the body of a microformats feed,
-     * so they are added to the headers when found, to be used later by get_links.
-     * @param \SimplePie\File $file
-     * @param string $hub
-     * @param string $self
-     */
-    private function store_links(&$file, $hub, $self)
-    {
-        if (isset($file->headers['link']['hub']) ||
-              (isset($file->headers['link']) &&
-               preg_match('/rel=hub/', $file->headers['link']))) {
-            return;
-        }
-
-        if ($hub) {
-            if (isset($file->headers['link'])) {
-                if ($file->headers['link'] !== '') {
-                    $file->headers['link'] = ', ';
-                }
-            } else {
-                $file->headers['link'] = '';
-            }
-            $file->headers['link'] .= '<'.$hub.'>; rel=hub';
-            if ($self) {
-                $file->headers['link'] .= ', <'.$self.'>; rel=self';
-            }
-        }
-    }
-
-    /**
-     * Get a DataCache
-     *
-     * @param string $feed_url Only needed for BC, can be removed in SimplePie 2.0.0
-     *
-     * @return DataCache
-     */
-    private function get_cache($feed_url = '')
-    {
-        if ($this->cache === null) {
-            // @trigger_error(sprintf('Not providing as PSR-16 cache implementation is deprecated since SimplePie 1.8.0, please use "SimplePie\SimplePie::set_cache()".'), \E_USER_DEPRECATED);
-            $cache = $this->registry->call(Cache::class, 'get_handler', [
-                $this->cache_location,
-                $this->get_cache_filename($feed_url),
-                Base::TYPE_FEED
-            ]);
-
-            return new BaseDataCache($cache);
-        }
-
-        return $this->cache;
-    }
-}
-
-class_alias('SimplePie\SimplePie', 'SimplePie');
-
-}
-
-namespace SimplePie {
-
-/**
- * Manages all author-related data
- *
- * Used by {@see Item::get_author()} and {@see SimplePie::get_authors()}
- *
- * This class can be overloaded with {@see SimplePie::set_author_class()}
- *
- * @package SimplePie
- * @subpackage API
- */
-class Author
-{
-    /**
-     * Author's name
-     *
-     * @var string
-     * @see get_name()
-     */
-    public $name;
-
-    /**
-     * Author's link
-     *
-     * @var string
-     * @see get_link()
-     */
-    public $link;
-
-    /**
-     * Author's email address
-     *
-     * @var string
-     * @see get_email()
-     */
-    public $email;
-
-    /**
-     * Constructor, used to input the data
-     *
-     * @param string $name
-     * @param string $link
-     * @param string $email
-     */
-    public function __construct($name = null, $link = null, $email = null)
-    {
-        $this->name = $name;
-        $this->link = $link;
-        $this->email = $email;
-    }
-
-    /**
-     * String-ified version
-     *
-     * @return string
-     */
-    public function __toString()
-    {
-        // There is no $this->data here
-        return md5(serialize($this));
-    }
-
-    /**
-     * Author's name
-     *
-     * @return string|null
-     */
-    public function get_name()
-    {
-        if ($this->name !== null) {
-            return $this->name;
-        }
-
-        return null;
-    }
-
-    /**
-     * Author's link
-     *
-     * @return string|null
-     */
-    public function get_link()
-    {
-        if ($this->link !== null) {
-            return $this->link;
-        }
-
-        return null;
-    }
-
-    /**
-     * Author's email address
-     *
-     * @return string|null
-     */
-    public function get_email()
-    {
-        if ($this->email !== null) {
-            return $this->email;
-        }
-
-        return null;
-    }
-}
-
-class_alias('SimplePie\Author', 'SimplePie_Author');
-
-}
-
-namespace SimplePie {
-
-use SimplePie\Cache\Base;
-
-/**
- * Used to create cache objects
- *
- * This class can be overloaded with {@see SimplePie::set_cache_class()},
- * although the preferred way is to create your own handler
- * via {@see register()}
- *
- * @package SimplePie
- * @subpackage Caching
- * @deprecated since SimplePie 1.8.0, use "SimplePie\SimplePie::set_cache()" instead
- */
-class Cache
-{
-    /**
-     * Cache handler classes
-     *
-     * These receive 3 parameters to their constructor, as documented in
-     * {@see register()}
-     * @var array
-     */
-    protected static $handlers = [
-        'mysql'     => 'SimplePie\Cache\MySQL',
-        'memcache'  => 'SimplePie\Cache\Memcache',
-        'memcached' => 'SimplePie\Cache\Memcached',
-        'redis'     => 'SimplePie\Cache\Redis'
-    ];
-
-    /**
-     * Don't call the constructor. Please.
-     */
-    private function __construct()
-    {
-    }
-
-    /**
-     * Create a new SimplePie\Cache object
-     *
-     * @param string $location URL location (scheme is used to determine handler)
-     * @param string $filename Unique identifier for cache object
-     * @param Base::TYPE_FEED|Base::TYPE_IMAGE $extension 'spi' or 'spc'
-     * @return Base Type of object depends on scheme of `$location`
-     */
-    public static function get_handler($location, $filename, $extension)
-    {
-        $type = explode(':', $location, 2);
-        $type = $type[0];
-        if (!empty(self::$handlers[$type])) {
-            $class = self::$handlers[$type];
-            return new $class($location, $filename, $extension);
-        }
-
-        return new \SimplePie\Cache\File($location, $filename, $extension);
-    }
-
-    /**
-     * Create a new SimplePie\Cache object
-     *
-     * @deprecated since SimplePie 1.3.1, use {@see get_handler()} instead
-     */
-    public function create($location, $filename, $extension)
-    {
-        trigger_error('Cache::create() has been replaced with Cache::get_handler() since SimplePie 1.3.1, use the registry system instead.', \E_USER_DEPRECATED);
-
-        return self::get_handler($location, $filename, $extension);
-    }
-
-    /**
-     * Register a handler
-     *
-     * @param string $type DSN type to register for
-     * @param class-string<Base> $class Name of handler class. Must implement Base
-     */
-    public static function register($type, $class)
-    {
-        self::$handlers[$type] = $class;
-    }
-
-    /**
-     * Parse a URL into an array
-     *
-     * @param string $url
-     * @return array
-     */
-    public static function parse_URL($url)
-    {
-        $params = parse_url($url);
-        $params['extras'] = [];
-        if (isset($params['query'])) {
-            parse_str($params['query'], $params['extras']);
-        }
-        return $params;
-    }
-}
-
-class_alias('SimplePie\Cache', 'SimplePie_Cache');
-
-}
-
-namespace SimplePie\Cache {
-
-/**
- * Base for cache objects
- *
- * Classes to be used with {@see \SimplePie\Cache::register()} are expected
- * to implement this interface.
- *
- * @package SimplePie
- * @subpackage Caching
- * @deprecated since SimplePie 1.8.0, use "Psr\SimpleCache\CacheInterface" instead
- */
-interface Base
-{
-    /**
-     * Feed cache type
-     *
-     * @var string
-     */
-    public const TYPE_FEED = 'spc';
-
-    /**
-     * Image cache type
-     *
-     * @var string
-     */
-    public const TYPE_IMAGE = 'spi';
-
-    /**
-     * Create a new cache object
-     *
-     * @param string $location Location string (from SimplePie::$cache_location)
-     * @param string $name Unique ID for the cache
-     * @param Base::TYPE_FEED|Base::TYPE_IMAGE $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
-     */
-    public function __construct($location, $name, $type);
-
-    /**
-     * Save data to the cache
-     *
-     * @param array|\SimplePie\SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
-     * @return bool Successfulness
-     */
-    public function save($data);
-
-    /**
-     * Retrieve the data saved to the cache
-     *
-     * @return array Data for SimplePie::$data
-     */
-    public function load();
-
-    /**
-     * Retrieve the last modified time for the cache
-     *
-     * @return int Timestamp
-     */
-    public function mtime();
-
-    /**
-     * Set the last modified time to the current time
-     *
-     * @return bool Success status
-     */
-    public function touch();
-
-    /**
-     * Remove the cache
-     *
-     * @return bool Success status
-     */
-    public function unlink();
-}
-
-class_alias('SimplePie\Cache\Base', 'SimplePie_Cache_Base');
-
-}
-
-namespace SimplePie\Cache {
-
-use InvalidArgumentException;
-
-/**
- * Adapter for deprecated \SimplePie\Cache\Base implementations
- *
- * @package SimplePie
- * @subpackage Caching
- * @internal
- */
-final class BaseDataCache implements DataCache
-{
-    /**
-     * @var Base
-     */
-    private $cache;
-
-    public function __construct(Base $cache)
-    {
-        $this->cache = $cache;
-    }
-
-    /**
-     * Fetches a value from the cache.
-     *
-     * Equivalent to \Psr\SimpleCache\CacheInterface::get()
-     * <code>
-     * public function get(string $key, mixed $default = null): mixed;
-     * </code>
-     *
-     * @param string $key     The unique key of this item in the cache.
-     * @param mixed  $default Default value to return if the key does not exist.
-     *
-     * @return array|mixed The value of the item from the cache, or $default in case of cache miss.
-     *
-     * @throws InvalidArgumentException
-     *   MUST be thrown if the $key string is not a legal value.
-     */
-    public function get_data(string $key, $default = null)
-    {
-        $data = $this->cache->load();
-
-        if (! is_array($data)) {
-            return $default;
-        }
-
-        // ignore data if internal cache expiration time is not set
-        if (! array_key_exists('__cache_expiration_time', $data)) {
-            return $default;
-        }
-
-        // ignore data if internal cache expiration time is expired
-        if ($data['__cache_expiration_time'] < time()) {
-            return $default;
-        }
-
-        // remove internal cache expiration time
-        unset($data['__cache_expiration_time']);
-
-        return $data;
-    }
-
-    /**
-     * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
-     *
-     * Equivalent to \Psr\SimpleCache\CacheInterface::set()
-     * <code>
-     * public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null): bool;
-     * </code>
-     *
-     * @param string   $key   The key of the item to store.
-     * @param array    $value The value of the item to store, must be serializable.
-     * @param null|int $ttl   Optional. The TTL value of this item. If no value is sent and
-     *                                      the driver supports TTL then the library may set a default value
-     *                                      for it or let the driver take care of that.
-     *
-     * @return bool True on success and false on failure.
-     *
-     * @throws InvalidArgumentException
-     *   MUST be thrown if the $key string is not a legal value.
-     */
-    public function set_data(string $key, array $value, ?int $ttl = null): bool
-    {
-        if ($ttl === null) {
-            $ttl = 3600;
-        }
-
-        // place internal cache expiration time
-        $value['__cache_expiration_time'] = time() + $ttl;
-
-        return $this->cache->save($value);
-    }
-
-    /**
-     * Delete an item from the cache by its unique key.
-     *
-     * Equivalent to \Psr\SimpleCache\CacheInterface::delete()
-     * <code>
-     * public function delete(string $key): bool;
-     * </code>
-     *
-     * @param string $key The unique cache key of the item to delete.
-     *
-     * @return bool True if the item was successfully removed. False if there was an error.
-     *
-     * @throws InvalidArgumentException
-     *   MUST be thrown if the $key string is not a legal value.
-     */
-    public function delete_data(string $key): bool
-    {
-        return $this->cache->unlink();
-    }
-}
-
-}
-
-namespace SimplePie\Cache {
-
-/**
- * Creating a cache filename with callables
- *
- * @package SimplePie
- * @subpackage Caching
- */
-final class CallableNameFilter implements NameFilter
-{
-    /**
-     * @var callable
-     */
-    private $callable;
-
-    public function __construct(callable $callable)
-    {
-        $this->callable = $callable;
-    }
-
-    /**
-     * Method to create cache filename with.
-     *
-     * The returning name MUST follow the rules for keys in PSR-16.
-     *
-     * @link https://www.php-fig.org/psr/psr-16/
-     *
-     * The returning name MUST be a string of at least one character
-     * that uniquely identifies a cached item, MUST only contain the
-     * characters A-Z, a-z, 0-9, _, and . in any order in UTF-8 encoding
-     * and MUST not longer then 64 characters. The following characters
-     * are reserved for future extensions and MUST NOT be used: {}()/\@:
-     *
-     * A provided implementing library MAY support additional characters
-     * and encodings or longer lengths, but MUST support at least that
-     * minimum.
-     *
-     * @param string $name The name for the cache will be most likly an url with query string
-     *
-     * @return string the new cache name
-     */
-    public function filter(string $name): string
-    {
-        return call_user_func($this->callable, $name);
-    }
-}
-
-}
-
-namespace SimplePie\Cache {
-
-/**
- * Base class for database-based caches
- *
- * @package SimplePie
- * @subpackage Caching
- * @deprecated since SimplePie 1.8.0, use implementation of "Psr\SimpleCache\CacheInterface" instead
- */
-abstract class DB implements Base
-{
-    /**
-     * Helper for database conversion
-     *
-     * Converts a given {@see SimplePie} object into data to be stored
-     *
-     * @param \SimplePie\SimplePie $data
-     * @return array First item is the serialized data for storage, second item is the unique ID for this item
-     */
-    protected static function prepare_simplepie_object_for_cache($data)
-    {
-        $items = $data->get_items();
-        $items_by_id = [];
-
-        if (!empty($items)) {
-            foreach ($items as $item) {
-                $items_by_id[$item->get_id()] = $item;
-            }
-
-            if (count($items_by_id) !== count($items)) {
-                $items_by_id = [];
-                foreach ($items as $item) {
-                    $items_by_id[$item->get_id(true)] = $item;
-                }
-            }
-
-            if (isset($data->data['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['feed'][0])) {
-                $channel =& $data->data['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['feed'][0];
-            } elseif (isset($data->data['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['feed'][0])) {
-                $channel =& $data->data['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['feed'][0];
-            } elseif (isset($data->data['child'][\SimplePie\SimplePie::NAMESPACE_RDF]['RDF'][0])) {
-                $channel =& $data->data['child'][\SimplePie\SimplePie::NAMESPACE_RDF]['RDF'][0];
-            } elseif (isset($data->data['child'][\SimplePie\SimplePie::NAMESPACE_RSS_20]['rss'][0]['child'][\SimplePie\SimplePie::NAMESPACE_RSS_20]['channel'][0])) {
-                $channel =& $data->data['child'][\SimplePie\SimplePie::NAMESPACE_RSS_20]['rss'][0]['child'][\SimplePie\SimplePie::NAMESPACE_RSS_20]['channel'][0];
-            } else {
-                $channel = null;
-            }
-
-            if ($channel !== null) {
-                if (isset($channel['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['entry'])) {
-                    unset($channel['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['entry']);
-                }
-                if (isset($channel['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['entry'])) {
-                    unset($channel['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['entry']);
-                }
-                if (isset($channel['child'][\SimplePie\SimplePie::NAMESPACE_RSS_10]['item'])) {
-                    unset($channel['child'][\SimplePie\SimplePie::NAMESPACE_RSS_10]['item']);
-                }
-                if (isset($channel['child'][\SimplePie\SimplePie::NAMESPACE_RSS_090]['item'])) {
-                    unset($channel['child'][\SimplePie\SimplePie::NAMESPACE_RSS_090]['item']);
-                }
-                if (isset($channel['child'][\SimplePie\SimplePie::NAMESPACE_RSS_20]['item'])) {
-                    unset($channel['child'][\SimplePie\SimplePie::NAMESPACE_RSS_20]['item']);
-                }
-            }
-            if (isset($data->data['items'])) {
-                unset($data->data['items']);
-            }
-            if (isset($data->data['ordered_items'])) {
-                unset($data->data['ordered_items']);
-            }
-        }
-        return [serialize($data->data), $items_by_id];
-    }
-}
-
-class_alias('SimplePie\Cache\DB', 'SimplePie_Cache_DB');
-
-}
-
-namespace SimplePie\Cache {
-
-use InvalidArgumentException;
-
-/**
- * Subset of PSR-16 Cache client for caching data arrays
- *
- * Only get(), set() and delete() methods are used,
- * but not has(), getMultiple(), setMultiple() or deleteMultiple().
- *
- * The methods names must be different, but should be compatible to the
- * methods of \Psr\SimpleCache\CacheInterface.
- *
- * @package SimplePie
- * @subpackage Caching
- * @internal
- */
-interface DataCache
-{
-    /**
-     * Fetches a value from the cache.
-     *
-     * Equivalent to \Psr\SimpleCache\CacheInterface::get()
-     * <code>
-     * public function get(string $key, mixed $default = null): mixed;
-     * </code>
-     *
-     * @param string   $key     The unique key of this item in the cache.
-     * @param mixed    $default Default value to return if the key does not exist.
-     *
-     * @return array|mixed The value of the item from the cache, or $default in case of cache miss.
-     *
-     * @throws InvalidArgumentException
-     *   MUST be thrown if the $key string is not a legal value.
-     */
-    public function get_data(string $key, $default = null);
-
-    /**
-     * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
-     *
-     * Equivalent to \Psr\SimpleCache\CacheInterface::set()
-     * <code>
-     * public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null): bool;
-     * </code>
-     *
-     * @param string   $key   The key of the item to store.
-     * @param array    $value The value of the item to store, must be serializable.
-     * @param null|int $ttl   Optional. The TTL value of this item. If no value is sent and
-     *                                      the driver supports TTL then the library may set a default value
-     *                                      for it or let the driver take care of that.
-     *
-     * @return bool True on success and false on failure.
-     *
-     * @throws InvalidArgumentException
-     *   MUST be thrown if the $key string is not a legal value.
-     */
-    public function set_data(string $key, array $value, ?int $ttl = null): bool;
-
-    /**
-     * Delete an item from the cache by its unique key.
-     *
-     * Equivalent to \Psr\SimpleCache\CacheInterface::delete()
-     * <code>
-     * public function delete(string $key): bool;
-     * </code>
-     *
-     * @param string $key The unique cache key of the item to delete.
-     *
-     * @return bool True if the item was successfully removed. False if there was an error.
-     *
-     * @throws InvalidArgumentException
-     *   MUST be thrown if the $key string is not a legal value.
-     */
-    public function delete_data(string $key): bool;
-}
-
-}
-
-namespace SimplePie\Cache {
-
-/**
- * Caches data to the filesystem
- *
- * @package SimplePie
- * @subpackage Caching
- * @deprecated since SimplePie 1.8.0, use implementation of "Psr\SimpleCache\CacheInterface" instead
- */
-class File implements Base
-{
-    /**
-     * Location string
-     *
-     * @see SimplePie::$cache_location
-     * @var string
-     */
-    protected $location;
-
-    /**
-     * Filename
-     *
-     * @var string
-     */
-    protected $filename;
-
-    /**
-     * File extension
-     *
-     * @var string
-     */
-    protected $extension;
-
-    /**
-     * File path
-     *
-     * @var string
-     */
-    protected $name;
-
-    /**
-     * Create a new cache object
-     *
-     * @param string $location Location string (from SimplePie::$cache_location)
-     * @param string $name Unique ID for the cache
-     * @param Base::TYPE_FEED|Base::TYPE_IMAGE $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
-     */
-    public function __construct($location, $name, $type)
-    {
-        $this->location = $location;
-        $this->filename = $name;
-        $this->extension = $type;
-        $this->name = "$this->location/$this->filename.$this->extension";
-    }
-
-    /**
-     * Save data to the cache
-     *
-     * @param array|\SimplePie\SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
-     * @return bool Successfulness
-     */
-    public function save($data)
-    {
-        if (file_exists($this->name) && is_writable($this->name) || file_exists($this->location) && is_writable($this->location)) {
-            if ($data instanceof \SimplePie\SimplePie) {
-                $data = $data->data;
-            }
-
-            $data = serialize($data);
-            return (bool) file_put_contents($this->name, $data);
-        }
-        return false;
-    }
-
-    /**
-     * Retrieve the data saved to the cache
-     *
-     * @return array Data for SimplePie::$data
-     */
-    public function load()
-    {
-        if (file_exists($this->name) && is_readable($this->name)) {
-            return unserialize(file_get_contents($this->name));
-        }
-        return false;
-    }
-
-    /**
-     * Retrieve the last modified time for the cache
-     *
-     * @return int Timestamp
-     */
-    public function mtime()
-    {
-        return @filemtime($this->name);
-    }
-
-    /**
-     * Set the last modified time to the current time
-     *
-     * @return bool Success status
-     */
-    public function touch()
-    {
-        return @touch($this->name);
-    }
-
-    /**
-     * Remove the cache
-     *
-     * @return bool Success status
-     */
-    public function unlink()
-    {
-        if (file_exists($this->name)) {
-            return unlink($this->name);
-        }
-        return false;
-    }
-}
-
-class_alias('SimplePie\Cache\File', 'SimplePie_Cache_File');
-
-}
-
-namespace SimplePie\Cache {
-
-use Memcache as NativeMemcache;
-
-/**
- * Caches data to memcache
- *
- * Registered for URLs with the "memcache" protocol
- *
- * For example, `memcache://localhost:11211/?timeout=3600&prefix=sp_` will
- * connect to memcache on `localhost` on port 11211. All tables will be
- * prefixed with `sp_` and data will expire after 3600 seconds
- *
- * @package SimplePie
- * @subpackage Caching
- * @uses Memcache
- * @deprecated since SimplePie 1.8.0, use implementation of "Psr\SimpleCache\CacheInterface" instead
- */
-class Memcache implements Base
-{
-    /**
-     * Memcache instance
-     *
-     * @var Memcache
-     */
-    protected $cache;
-
-    /**
-     * Options
-     *
-     * @var array
-     */
-    protected $options;
-
-    /**
-     * Cache name
-     *
-     * @var string
-     */
-    protected $name;
-
-    /**
-     * Create a new cache object
-     *
-     * @param string $location Location string (from SimplePie::$cache_location)
-     * @param string $name Unique ID for the cache
-     * @param Base::TYPE_FEED|Base::TYPE_IMAGE $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
-     */
-    public function __construct($location, $name, $type)
-    {
-        $this->options = [
-            'host' => '127.0.0.1',
-            'port' => 11211,
-            'extras' => [
-                'timeout' => 3600, // one hour
-                'prefix' => 'simplepie_',
-            ],
-        ];
-        $this->options = array_replace_recursive($this->options, \SimplePie\Cache::parse_URL($location));
-
-        $this->name = $this->options['extras']['prefix'] . md5("$name:$type");
-
-        $this->cache = new NativeMemcache();
-        $this->cache->addServer($this->options['host'], (int) $this->options['port']);
-    }
-
-    /**
-     * Save data to the cache
-     *
-     * @param array|\SimplePie\SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
-     * @return bool Successfulness
-     */
-    public function save($data)
-    {
-        if ($data instanceof \SimplePie\SimplePie) {
-            $data = $data->data;
-        }
-        return $this->cache->set($this->name, serialize($data), MEMCACHE_COMPRESSED, (int) $this->options['extras']['timeout']);
-    }
-
-    /**
-     * Retrieve the data saved to the cache
-     *
-     * @return array Data for SimplePie::$data
-     */
-    public function load()
-    {
-        $data = $this->cache->get($this->name);
-
-        if ($data !== false) {
-            return unserialize($data);
-        }
-        return false;
-    }
-
-    /**
-     * Retrieve the last modified time for the cache
-     *
-     * @return int Timestamp
-     */
-    public function mtime()
-    {
-        $data = $this->cache->get($this->name);
-
-        if ($data !== false) {
-            // essentially ignore the mtime because Memcache expires on its own
-            return time();
-        }
-
-        return false;
-    }
-
-    /**
-     * Set the last modified time to the current time
-     *
-     * @return bool Success status
-     */
-    public function touch()
-    {
-        $data = $this->cache->get($this->name);
-
-        if ($data !== false) {
-            return $this->cache->set($this->name, $data, MEMCACHE_COMPRESSED, (int) $this->options['extras']['timeout']);
-        }
-
-        return false;
-    }
-
-    /**
-     * Remove the cache
-     *
-     * @return bool Success status
-     */
-    public function unlink()
-    {
-        return $this->cache->delete($this->name, 0);
-    }
-}
-
-class_alias('SimplePie\Cache\Memcache', 'SimplePie_Cache_Memcache');
-
-}
-
-namespace SimplePie\Cache {
-
-use Memcached as NativeMemcached;
-
-/**
- * Caches data to memcached
- *
- * Registered for URLs with the "memcached" protocol
- *
- * For example, `memcached://localhost:11211/?timeout=3600&prefix=sp_` will
- * connect to memcached on `localhost` on port 11211. All tables will be
- * prefixed with `sp_` and data will expire after 3600 seconds
- *
- * @package    SimplePie
- * @subpackage Caching
- * @author     Paul L. McNeely
- * @uses       Memcached
- * @deprecated since SimplePie 1.8.0, use implementation of "Psr\SimpleCache\CacheInterface" instead
- */
-class Memcached implements Base
-{
-    /**
-     * NativeMemcached instance
-     * @var NativeMemcached
-     */
-    protected $cache;
-
-    /**
-     * Options
-     * @var array
-     */
-    protected $options;
-
-    /**
-     * Cache name
-     * @var string
-     */
-    protected $name;
-
-    /**
-     * Create a new cache object
-     * @param string $location Location string (from SimplePie::$cache_location)
-     * @param string $name Unique ID for the cache
-     * @param Base::TYPE_FEED|Base::TYPE_IMAGE $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
-     */
-    public function __construct($location, $name, $type)
-    {
-        $this->options = [
-            'host'   => '127.0.0.1',
-            'port'   => 11211,
-            'extras' => [
-                'timeout' => 3600, // one hour
-                'prefix'  => 'simplepie_',
-            ],
-        ];
-        $this->options = array_replace_recursive($this->options, \SimplePie\Cache::parse_URL($location));
-
-        $this->name = $this->options['extras']['prefix'] . md5("$name:$type");
-
-        $this->cache = new NativeMemcached();
-        $this->cache->addServer($this->options['host'], (int)$this->options['port']);
-    }
-
-    /**
-     * Save data to the cache
-     * @param array|\SimplePie\SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
-     * @return bool Successfulness
-     */
-    public function save($data)
-    {
-        if ($data instanceof \SimplePie\SimplePie) {
-            $data = $data->data;
-        }
-
-        return $this->setData(serialize($data));
-    }
-
-    /**
-     * Retrieve the data saved to the cache
-     * @return array Data for SimplePie::$data
-     */
-    public function load()
-    {
-        $data = $this->cache->get($this->name);
-
-        if ($data !== false) {
-            return unserialize($data);
-        }
-        return false;
-    }
-
-    /**
-     * Retrieve the last modified time for the cache
-     * @return int Timestamp
-     */
-    public function mtime()
-    {
-        $data = $this->cache->get($this->name . '_mtime');
-        return (int) $data;
-    }
-
-    /**
-     * Set the last modified time to the current time
-     * @return bool Success status
-     */
-    public function touch()
-    {
-        $data = $this->cache->get($this->name);
-        return $this->setData($data);
-    }
-
-    /**
-     * Remove the cache
-     * @return bool Success status
-     */
-    public function unlink()
-    {
-        return $this->cache->delete($this->name, 0);
-    }
-
-    /**
-     * Set the last modified time and data to NativeMemcached
-     * @return bool Success status
-     */
-    private function setData($data)
-    {
-        if ($data !== false) {
-            $this->cache->set($this->name . '_mtime', time(), (int)$this->options['extras']['timeout']);
-            return $this->cache->set($this->name, $data, (int)$this->options['extras']['timeout']);
-        }
-
-        return false;
-    }
-}
-
-class_alias('SimplePie\Cache\Memcached', 'SimplePie_Cache_Memcached');
-
-}
-
-namespace SimplePie\Cache {
-
-/**
- * Caches data to a MySQL database
- *
- * Registered for URLs with the "mysql" protocol
- *
- * For example, `mysql://root:password@localhost:3306/mydb?prefix=sp_` will
- * connect to the `mydb` database on `localhost` on port 3306, with the user
- * `root` and the password `password`. All tables will be prefixed with `sp_`
- *
- * @package SimplePie
- * @subpackage Caching
- * @deprecated since SimplePie 1.8.0, use implementation of "Psr\SimpleCache\CacheInterface" instead
- */
-class MySQL extends DB
-{
-    /**
-     * PDO instance
-     *
-     * @var \PDO
-     */
-    protected $mysql;
-
-    /**
-     * Options
-     *
-     * @var array
-     */
-    protected $options;
-
-    /**
-     * Cache ID
-     *
-     * @var string
-     */
-    protected $id;
-
-    /**
-     * Create a new cache object
-     *
-     * @param string $location Location string (from SimplePie::$cache_location)
-     * @param string $name Unique ID for the cache
-     * @param Base::TYPE_FEED|Base::TYPE_IMAGE $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
-     */
-    public function __construct($location, $name, $type)
-    {
-        $this->options = [
-            'user' => null,
-            'pass' => null,
-            'host' => '127.0.0.1',
-            'port' => '3306',
-            'path' => '',
-            'extras' => [
-                'prefix' => '',
-                'cache_purge_time' => 2592000
-            ],
-        ];
-
-        $this->options = array_replace_recursive($this->options, \SimplePie\Cache::parse_URL($location));
-
-        // Path is prefixed with a "/"
-        $this->options['dbname'] = substr($this->options['path'], 1);
-
-        try {
-            $this->mysql = new \PDO("mysql:dbname={$this->options['dbname']};host={$this->options['host']};port={$this->options['port']}", $this->options['user'], $this->options['pass'], [\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8']);
-        } catch (\PDOException $e) {
-            $this->mysql = null;
-            return;
-        }
-
-        $this->id = $name . $type;
-
-        if (!$query = $this->mysql->query('SHOW TABLES')) {
-            $this->mysql = null;
-            return;
-        }
-
-        $db = [];
-        while ($row = $query->fetchColumn()) {
-            $db[] = $row;
-        }
-
-        if (!in_array($this->options['extras']['prefix'] . 'cache_data', $db)) {
-            $query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))');
-            if ($query === false) {
-                trigger_error("Can't create " . $this->options['extras']['prefix'] . "cache_data table, check permissions", \E_USER_WARNING);
-                $this->mysql = null;
-                return;
-            }
-        }
-
-        if (!in_array($this->options['extras']['prefix'] . 'items', $db)) {
-            $query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` MEDIUMBLOB NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))');
-            if ($query === false) {
-                trigger_error("Can't create " . $this->options['extras']['prefix'] . "items table, check permissions", \E_USER_WARNING);
-                $this->mysql = null;
-                return;
-            }
-        }
-    }
-
-    /**
-     * Save data to the cache
-     *
-     * @param array|\SimplePie\SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
-     * @return bool Successfulness
-     */
-    public function save($data)
-    {
-        if ($this->mysql === null) {
-            return false;
-        }
-
-        $query = $this->mysql->prepare('DELETE i, cd FROM `' . $this->options['extras']['prefix'] . 'cache_data` cd, ' .
-            '`' . $this->options['extras']['prefix'] . 'items` i ' .
-            'WHERE cd.id = i.feed_id ' .
-            'AND cd.mtime < (unix_timestamp() - :purge_time)');
-        $query->bindValue(':purge_time', $this->options['extras']['cache_purge_time']);
-
-        if (!$query->execute()) {
-            return false;
-        }
-
-        if ($data instanceof \SimplePie\SimplePie) {
-            $data = clone $data;
-
-            $prepared = self::prepare_simplepie_object_for_cache($data);
-
-            $query = $this->mysql->prepare('SELECT COUNT(*) FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
-            $query->bindValue(':feed', $this->id);
-            if ($query->execute()) {
-                if ($query->fetchColumn() > 0) {
-                    $items = count($prepared[1]);
-                    if ($items) {
-                        $sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = :items, `data` = :data, `mtime` = :time WHERE `id` = :feed';
-                        $query = $this->mysql->prepare($sql);
-                        $query->bindValue(':items', $items);
-                    } else {
-                        $sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `data` = :data, `mtime` = :time WHERE `id` = :feed';
-                        $query = $this->mysql->prepare($sql);
-                    }
-
-                    $query->bindValue(':data', $prepared[0]);
-                    $query->bindValue(':time', time());
-                    $query->bindValue(':feed', $this->id);
-                    if (!$query->execute()) {
-                        return false;
-                    }
-                } else {
-                    $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:feed, :count, :data, :time)');
-                    $query->bindValue(':feed', $this->id);
-                    $query->bindValue(':count', count($prepared[1]));
-                    $query->bindValue(':data', $prepared[0]);
-                    $query->bindValue(':time', time());
-                    if (!$query->execute()) {
-                        return false;
-                    }
-                }
-
-                $ids = array_keys($prepared[1]);
-                if (!empty($ids)) {
-                    foreach ($ids as $id) {
-                        $database_ids[] = $this->mysql->quote($id);
-                    }
-
-                    $query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `id` = ' . implode(' OR `id` = ', $database_ids) . ' AND `feed_id` = :feed');
-                    $query->bindValue(':feed', $this->id);
-
-                    if ($query->execute()) {
-                        $existing_ids = [];
-                        while ($row = $query->fetchColumn()) {
-                            $existing_ids[] = $row;
-                        }
-
-                        $new_ids = array_diff($ids, $existing_ids);
-
-                        foreach ($new_ids as $new_id) {
-                            if (!($date = $prepared[1][$new_id]->get_date('U'))) {
-                                $date = time();
-                            }
-
-                            $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(:feed, :id, :data, :date)');
-                            $query->bindValue(':feed', $this->id);
-                            $query->bindValue(':id', $new_id);
-                            $query->bindValue(':data', serialize($prepared[1][$new_id]->data));
-                            $query->bindValue(':date', $date);
-                            if (!$query->execute()) {
-                                return false;
-                            }
-                        }
-                        return true;
-                    }
-                } else {
-                    return true;
-                }
-            }
-        } else {
-            $query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
-            $query->bindValue(':feed', $this->id);
-            if ($query->execute()) {
-                if ($query->rowCount() > 0) {
-                    $query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = 0, `data` = :data, `mtime` = :time WHERE `id` = :feed');
-                    $query->bindValue(':data', serialize($data));
-                    $query->bindValue(':time', time());
-                    $query->bindValue(':feed', $this->id);
-                    if ($query->execute()) {
-                        return true;
-                    }
-                } else {
-                    $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:id, 0, :data, :time)');
-                    $query->bindValue(':id', $this->id);
-                    $query->bindValue(':data', serialize($data));
-                    $query->bindValue(':time', time());
-                    if ($query->execute()) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Retrieve the data saved to the cache
-     *
-     * @return array Data for SimplePie::$data
-     */
-    public function load()
-    {
-        if ($this->mysql === null) {
-            return false;
-        }
-
-        $query = $this->mysql->prepare('SELECT `items`, `data` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
-        $query->bindValue(':id', $this->id);
-        if ($query->execute() && ($row = $query->fetch())) {
-            $data = unserialize($row[1]);
-
-            if (isset($this->options['items'][0])) {
-                $items = (int) $this->options['items'][0];
-            } else {
-                $items = (int) $row[0];
-            }
-
-            if ($items !== 0) {
-                if (isset($data['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['feed'][0])) {
-                    $feed =& $data['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['feed'][0];
-                } elseif (isset($data['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['feed'][0])) {
-                    $feed =& $data['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['feed'][0];
-                } elseif (isset($data['child'][\SimplePie\SimplePie::NAMESPACE_RDF]['RDF'][0])) {
-                    $feed =& $data['child'][\SimplePie\SimplePie::NAMESPACE_RDF]['RDF'][0];
-                } elseif (isset($data['child'][\SimplePie\SimplePie::NAMESPACE_RSS_20]['rss'][0])) {
-                    $feed =& $data['child'][\SimplePie\SimplePie::NAMESPACE_RSS_20]['rss'][0];
-                } else {
-                    $feed = null;
-                }
-
-                if ($feed !== null) {
-                    $sql = 'SELECT `data` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :feed ORDER BY `posted` DESC';
-                    if ($items > 0) {
-                        $sql .= ' LIMIT ' . $items;
-                    }
-
-                    $query = $this->mysql->prepare($sql);
-                    $query->bindValue(':feed', $this->id);
-                    if ($query->execute()) {
-                        while ($row = $query->fetchColumn()) {
-                            $feed['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['entry'][] = unserialize($row);
-                        }
-                    } else {
-                        return false;
-                    }
-                }
-            }
-            return $data;
-        }
-        return false;
-    }
-
-    /**
-     * Retrieve the last modified time for the cache
-     *
-     * @return int Timestamp
-     */
-    public function mtime()
-    {
-        if ($this->mysql === null) {
-            return false;
-        }
-
-        $query = $this->mysql->prepare('SELECT `mtime` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
-        $query->bindValue(':id', $this->id);
-        if ($query->execute() && ($time = $query->fetchColumn())) {
-            return $time;
-        }
-
-        return false;
-    }
-
-    /**
-     * Set the last modified time to the current time
-     *
-     * @return bool Success status
-     */
-    public function touch()
-    {
-        if ($this->mysql === null) {
-            return false;
-        }
-
-        $query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `mtime` = :time WHERE `id` = :id');
-        $query->bindValue(':time', time());
-        $query->bindValue(':id', $this->id);
-
-        return $query->execute() && $query->rowCount() > 0;
-    }
-
-    /**
-     * Remove the cache
-     *
-     * @return bool Success status
-     */
-    public function unlink()
-    {
-        if ($this->mysql === null) {
-            return false;
-        }
-
-        $query = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
-        $query->bindValue(':id', $this->id);
-        $query2 = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :id');
-        $query2->bindValue(':id', $this->id);
-
-        return $query->execute() && $query2->execute();
-    }
-}
-
-class_alias('SimplePie\Cache\MySQL', 'SimplePie_Cache_MySQL');
-
-}
-
-namespace SimplePie\Cache {
-
-/**
- * Interface for creating a cache filename
- *
- * @package SimplePie
- * @subpackage Caching
- */
-interface NameFilter
-{
-    /**
-     * Method to create cache filename with.
-     *
-     * The returning name MUST follow the rules for keys in PSR-16.
-     *
-     * @link https://www.php-fig.org/psr/psr-16/
-     *
-     * The returning name MUST be a string of at least one character
-     * that uniquely identifies a cached item, MUST only contain the
-     * characters A-Z, a-z, 0-9, _, and . in any order in UTF-8 encoding
-     * and MUST not longer then 64 characters. The following characters
-     * are reserved for future extensions and MUST NOT be used: {}()/\@:
-     *
-     * A provided implementing library MAY support additional characters
-     * and encodings or longer lengths, but MUST support at least that
-     * minimum.
-     *
-     * @param string $name The name for the cache will be most likly an url with query string
-     *
-     * @return string the new cache name
-     */
-    public function filter(string $name): string;
-}
-
-}
-
-namespace SimplePie\Cache {
-
-use Psr\SimpleCache\CacheInterface;
-use Psr\SimpleCache\InvalidArgumentException;
-
-/**
- * Caches data into a PSR-16 cache implementation
- *
- * @package SimplePie
- * @subpackage Caching
- * @internal
- */
-final class Psr16 implements DataCache
-{
-    /**
-     * PSR-16 cache implementation
-     *
-     * @var CacheInterface
-     */
-    private $cache;
-
-    /**
-     * PSR-16 cache implementation
-     *
-     * @param CacheInterface $cache
-     */
-    public function __construct(CacheInterface $cache)
-    {
-        $this->cache = $cache;
-    }
-
-    /**
-     * Fetches a value from the cache.
-     *
-     * Equivalent to \Psr\SimpleCache\CacheInterface::get()
-     * <code>
-     * public function get(string $key, mixed $default = null): mixed;
-     * </code>
-     *
-     * @param string $key     The unique key of this item in the cache.
-     * @param mixed  $default Default value to return if the key does not exist.
-     *
-     * @return array|mixed The value of the item from the cache, or $default in case of cache miss.
-     *
-     * @throws InvalidArgumentException
-     *   MUST be thrown if the $key string is not a legal value.
-     */
-    public function get_data(string $key, $default = null)
-    {
-        $data = $this->cache->get($key, $default);
-
-        if (! is_array($data) || $data === $default) {
-            return $default;
-        }
-
-        return $data;
-    }
-
-    /**
-     * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
-     *
-     * Equivalent to \Psr\SimpleCache\CacheInterface::set()
-     * <code>
-     * public function set(string $key, mixed $value, null|int|\DateInterval $ttl = null): bool;
-     * </code>
-     *
-     * @param string   $key   The key of the item to store.
-     * @param array    $value The value of the item to store, must be serializable.
-     * @param null|int $ttl   Optional. The TTL value of this item. If no value is sent and
-     *                                      the driver supports TTL then the library may set a default value
-     *                                      for it or let the driver take care of that.
-     *
-     * @return bool True on success and false on failure.
-     *
-     * @throws InvalidArgumentException
-     *   MUST be thrown if the $key string is not a legal value.
-     */
-    public function set_data(string $key, array $value, ?int $ttl = null): bool
-    {
-        return $this->cache->set($key, $value, $ttl);
-    }
-
-    /**
-     * Delete an item from the cache by its unique key.
-     *
-     * Equivalent to \Psr\SimpleCache\CacheInterface::delete()
-     * <code>
-     * public function delete(string $key): bool;
-     * </code>
-     *
-     * @param string $key The unique cache key of the item to delete.
-     *
-     * @return bool True if the item was successfully removed. False if there was an error.
-     *
-     * @throws InvalidArgumentException
-     *   MUST be thrown if the $key string is not a legal value.
-     */
-    public function delete_data(string $key): bool
-    {
-        return $this->cache->delete($key);
-    }
-}
-
-}
-
-namespace SimplePie\Cache {
-
-use Redis as NativeRedis;
-
-/**
- * Caches data to redis
- *
- * Registered for URLs with the "redis" protocol
- *
- * For example, `redis://localhost:6379/?timeout=3600&prefix=sp_&dbIndex=0` will
- * connect to redis on `localhost` on port 6379. All tables will be
- * prefixed with `simple_primary-` and data will expire after 3600 seconds
- *
- * @package SimplePie
- * @subpackage Caching
- * @uses Redis
- * @deprecated since SimplePie 1.8.0, use implementation of "Psr\SimpleCache\CacheInterface" instead
- */
-class Redis implements Base
-{
-    /**
-     * Redis instance
-     *
-     * @var NativeRedis
-     */
-    protected $cache;
-
-    /**
-     * Options
-     *
-     * @var array
-     */
-    protected $options;
-
-    /**
-     * Cache name
-     *
-     * @var string
-     */
-    protected $name;
-
-    /**
-     * Create a new cache object
-     *
-     * @param string $location Location string (from SimplePie::$cache_location)
-     * @param string $name Unique ID for the cache
-     * @param Base::TYPE_FEED|Base::TYPE_IMAGE $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
-     */
-    public function __construct($location, $name, $options = null)
-    {
-        //$this->cache = \flow\simple\cache\Redis::getRedisClientInstance();
-        $parsed = \SimplePie\Cache::parse_URL($location);
-        $redis = new NativeRedis();
-        $redis->connect($parsed['host'], $parsed['port']);
-        if (isset($parsed['pass'])) {
-            $redis->auth($parsed['pass']);
-        }
-        if (isset($parsed['path'])) {
-            $redis->select((int)substr($parsed['path'], 1));
-        }
-        $this->cache = $redis;
-
-        if (!is_null($options) && is_array($options)) {
-            $this->options = $options;
-        } else {
-            $this->options = [
-                'prefix' => 'rss:simple_primary:',
-                'expire' => 0,
-            ];
-        }
-
-        $this->name = $this->options['prefix'] . $name;
-    }
-
-    /**
-     * @param NativeRedis $cache
-     */
-    public function setRedisClient(NativeRedis $cache)
-    {
-        $this->cache = $cache;
-    }
-
-    /**
-     * Save data to the cache
-     *
-     * @param array|\SimplePie\SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
-     * @return bool Successfulness
-     */
-    public function save($data)
-    {
-        if ($data instanceof \SimplePie\SimplePie) {
-            $data = $data->data;
-        }
-        $response = $this->cache->set($this->name, serialize($data));
-        if ($this->options['expire']) {
-            $this->cache->expire($this->name, $this->options['expire']);
-        }
-
-        return $response;
-    }
-
-    /**
-     * Retrieve the data saved to the cache
-     *
-     * @return array Data for SimplePie::$data
-     */
-    public function load()
-    {
-        $data = $this->cache->get($this->name);
-
-        if ($data !== false) {
-            return unserialize($data);
-        }
-        return false;
-    }
-
-    /**
-     * Retrieve the last modified time for the cache
-     *
-     * @return int Timestamp
-     */
-    public function mtime()
-    {
-        $data = $this->cache->get($this->name);
-
-        if ($data !== false) {
-            return time();
-        }
-
-        return false;
-    }
-
-    /**
-     * Set the last modified time to the current time
-     *
-     * @return bool Success status
-     */
-    public function touch()
-    {
-        $data = $this->cache->get($this->name);
-
-        if ($data !== false) {
-            $return = $this->cache->set($this->name, $data);
-            if ($this->options['expire']) {
-                return $this->cache->expire($this->name, $this->options['expire']);
-            }
-            return $return;
-        }
-
-        return false;
-    }
-
-    /**
-     * Remove the cache
-     *
-     * @return bool Success status
-     */
-    public function unlink()
-    {
-        return $this->cache->set($this->name, null);
-    }
-}
-
-class_alias('SimplePie\Cache\Redis', 'SimplePie_Cache_Redis');
-
-}
-
-namespace SimplePie {
-
-/**
- * Handles `<media:text>` captions as defined in Media RSS.
- *
- * Used by {@see \SimplePie\Enclosure::get_caption()} and {@see \SimplePie\Enclosure::get_captions()}
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_caption_class()}
- *
- * @package SimplePie
- * @subpackage API
- */
-class Caption
-{
-    /**
-     * Content type
-     *
-     * @var string
-     * @see get_type()
-     */
-    public $type;
-
-    /**
-     * Language
-     *
-     * @var string
-     * @see get_language()
-     */
-    public $lang;
-
-    /**
-     * Start time
-     *
-     * @var string
-     * @see get_starttime()
-     */
-    public $startTime;
-
-    /**
-     * End time
-     *
-     * @var string
-     * @see get_endtime()
-     */
-    public $endTime;
-
-    /**
-     * Caption text
-     *
-     * @var string
-     * @see get_text()
-     */
-    public $text;
-
-    /**
-     * Constructor, used to input the data
-     *
-     * For documentation on all the parameters, see the corresponding
-     * properties and their accessors
-     */
-    public function __construct($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
-    {
-        $this->type = $type;
-        $this->lang = $lang;
-        $this->startTime = $startTime;
-        $this->endTime = $endTime;
-        $this->text = $text;
-    }
-
-    /**
-     * String-ified version
-     *
-     * @return string
-     */
-    public function __toString()
-    {
-        // There is no $this->data here
-        return md5(serialize($this));
-    }
-
-    /**
-     * Get the end time
-     *
-     * @return string|null Time in the format 'hh:mm:ss.SSS'
-     */
-    public function get_endtime()
-    {
-        if ($this->endTime !== null) {
-            return $this->endTime;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the language
-     *
-     * @link http://tools.ietf.org/html/rfc3066
-     * @return string|null Language code as per RFC 3066
-     */
-    public function get_language()
-    {
-        if ($this->lang !== null) {
-            return $this->lang;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the start time
-     *
-     * @return string|null Time in the format 'hh:mm:ss.SSS'
-     */
-    public function get_starttime()
-    {
-        if ($this->startTime !== null) {
-            return $this->startTime;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the text of the caption
-     *
-     * @return string|null
-     */
-    public function get_text()
-    {
-        if ($this->text !== null) {
-            return $this->text;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the content type (not MIME type)
-     *
-     * @return string|null Either 'text' or 'html'
-     */
-    public function get_type()
-    {
-        if ($this->type !== null) {
-            return $this->type;
-        }
-
-        return null;
-    }
-}
-
-class_alias('SimplePie\Caption', 'SimplePie_Caption');
-
-}
-
-namespace SimplePie {
-
-/**
- * Manages all category-related data
- *
- * Used by {@see \SimplePie\Item::get_category()} and {@see \SimplePie\Item::get_categories()}
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_category_class()}
- *
- * @package SimplePie
- * @subpackage API
- */
-class Category
-{
-    /**
-     * Category identifier
-     *
-     * @var string|null
-     * @see get_term
-     */
-    public $term;
-
-    /**
-     * Categorization scheme identifier
-     *
-     * @var string|null
-     * @see get_scheme()
-     */
-    public $scheme;
-
-    /**
-     * Human readable label
-     *
-     * @var string|null
-     * @see get_label()
-     */
-    public $label;
-
-    /**
-     * Category type
-     *
-     * category for <category>
-     * subject for <dc:subject>
-     *
-     * @var string|null
-     * @see get_type()
-     */
-    public $type;
-
-    /**
-     * Constructor, used to input the data
-     *
-     * @param string|null $term
-     * @param string|null $scheme
-     * @param string|null $label
-     * @param string|null $type
-     */
-    public function __construct($term = null, $scheme = null, $label = null, $type = null)
-    {
-        $this->term = $term;
-        $this->scheme = $scheme;
-        $this->label = $label;
-        $this->type = $type;
-    }
-
-    /**
-     * String-ified version
-     *
-     * @return string
-     */
-    public function __toString()
-    {
-        // There is no $this->data here
-        return md5(serialize($this));
-    }
-
-    /**
-     * Get the category identifier
-     *
-     * @return string|null
-     */
-    public function get_term()
-    {
-        return $this->term;
-    }
-
-    /**
-     * Get the categorization scheme identifier
-     *
-     * @return string|null
-     */
-    public function get_scheme()
-    {
-        return $this->scheme;
-    }
-
-    /**
-     * Get the human readable label
-     *
-     * @param bool $strict
-     * @return string|null
-     */
-    public function get_label($strict = false)
-    {
-        if ($this->label === null && $strict !== true) {
-            return $this->get_term();
-        }
-        return $this->label;
-    }
-
-    /**
-     * Get the category type
-     *
-     * @return string|null
-     */
-    public function get_type()
-    {
-        return $this->type;
-    }
-}
-
-class_alias('SimplePie\Category', 'SimplePie_Category');
-
-}
-
-namespace SimplePie\Content\Type {
-
-/**
- * Content-type sniffing
- *
- * Based on the rules in http://tools.ietf.org/html/draft-abarth-mime-sniff-06
- *
- * This is used since we can't always trust Content-Type headers, and is based
- * upon the HTML5 parsing rules.
- *
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_content_type_sniffer_class()}
- *
- * @package SimplePie
- * @subpackage HTTP
- */
-class Sniffer
-{
-    /**
-     * File object
-     *
-     * @var \SimplePie\File
-     */
-    public $file;
-
-    /**
-     * Create an instance of the class with the input file
-     *
-     * @param Sniffer $file Input file
-     */
-    public function __construct($file)
-    {
-        $this->file = $file;
-    }
-
-    /**
-     * Get the Content-Type of the specified file
-     *
-     * @return string Actual Content-Type
-     */
-    public function get_type()
-    {
-        if (isset($this->file->headers['content-type'])) {
-            if (!isset($this->file->headers['content-encoding'])
-                && ($this->file->headers['content-type'] === 'text/plain'
-                    || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
-                    || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'
-                    || $this->file->headers['content-type'] === 'text/plain; charset=UTF-8')) {
-                return $this->text_or_binary();
-            }
-
-            if (($pos = strpos($this->file->headers['content-type'], ';')) !== false) {
-                $official = substr($this->file->headers['content-type'], 0, $pos);
-            } else {
-                $official = $this->file->headers['content-type'];
-            }
-            $official = trim(strtolower($official));
-
-            if ($official === 'unknown/unknown'
-                || $official === 'application/unknown') {
-                return $this->unknown();
-            } elseif (substr($official, -4) === '+xml'
-                || $official === 'text/xml'
-                || $official === 'application/xml') {
-                return $official;
-            } elseif (substr($official, 0, 6) === 'image/') {
-                if ($return = $this->image()) {
-                    return $return;
-                }
-
-                return $official;
-            } elseif ($official === 'text/html') {
-                return $this->feed_or_html();
-            }
-
-            return $official;
-        }
-
-        return $this->unknown();
-    }
-
-    /**
-     * Sniff text or binary
-     *
-     * @return string Actual Content-Type
-     */
-    public function text_or_binary()
-    {
-        if (substr($this->file->body, 0, 2) === "\xFE\xFF"
-            || substr($this->file->body, 0, 2) === "\xFF\xFE"
-            || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
-            || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF") {
-            return 'text/plain';
-        } elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body)) {
-            return 'application/octet-stream';
-        }
-
-        return 'text/plain';
-    }
-
-    /**
-     * Sniff unknown
-     *
-     * @return string Actual Content-Type
-     */
-    public function unknown()
-    {
-        $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
-        if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
-            || strtolower(substr($this->file->body, $ws, 5)) === '<html'
-            || strtolower(substr($this->file->body, $ws, 7)) === '<script') {
-            return 'text/html';
-        } elseif (substr($this->file->body, 0, 5) === '%PDF-') {
-            return 'application/pdf';
-        } elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-') {
-            return 'application/postscript';
-        } elseif (substr($this->file->body, 0, 6) === 'GIF87a'
-            || substr($this->file->body, 0, 6) === 'GIF89a') {
-            return 'image/gif';
-        } elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") {
-            return 'image/png';
-        } elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF") {
-            return 'image/jpeg';
-        } elseif (substr($this->file->body, 0, 2) === "\x42\x4D") {
-            return 'image/bmp';
-        } elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00") {
-            return 'image/vnd.microsoft.icon';
-        }
-
-        return $this->text_or_binary();
-    }
-
-    /**
-     * Sniff images
-     *
-     * @return string Actual Content-Type
-     */
-    public function image()
-    {
-        if (substr($this->file->body, 0, 6) === 'GIF87a'
-            || substr($this->file->body, 0, 6) === 'GIF89a') {
-            return 'image/gif';
-        } elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") {
-            return 'image/png';
-        } elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF") {
-            return 'image/jpeg';
-        } elseif (substr($this->file->body, 0, 2) === "\x42\x4D") {
-            return 'image/bmp';
-        } elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00") {
-            return 'image/vnd.microsoft.icon';
-        }
-
-        return false;
-    }
-
-    /**
-     * Sniff HTML
-     *
-     * @return string Actual Content-Type
-     */
-    public function feed_or_html()
-    {
-        $len = strlen($this->file->body);
-        $pos = strspn($this->file->body, "\x09\x0A\x0D\x20\xEF\xBB\xBF");
-
-        while ($pos < $len) {
-            switch ($this->file->body[$pos]) {
-                case "\x09":
-                case "\x0A":
-                case "\x0D":
-                case "\x20":
-                    $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
-                    continue 2;
-
-                case '<':
-                    $pos++;
-                    break;
-
-                default:
-                    return 'text/html';
-            }
-
-            if (substr($this->file->body, $pos, 3) === '!--') {
-                $pos += 3;
-                if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false) {
-                    $pos += 3;
-                } else {
-                    return 'text/html';
-                }
-            } elseif (substr($this->file->body, $pos, 1) === '!') {
-                if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false) {
-                    $pos++;
-                } else {
-                    return 'text/html';
-                }
-            } elseif (substr($this->file->body, $pos, 1) === '?') {
-                if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false) {
-                    $pos += 2;
-                } else {
-                    return 'text/html';
-                }
-            } elseif (substr($this->file->body, $pos, 3) === 'rss'
-                || substr($this->file->body, $pos, 7) === 'rdf:RDF') {
-                return 'application/rss+xml';
-            } elseif (substr($this->file->body, $pos, 4) === 'feed') {
-                return 'application/atom+xml';
-            } else {
-                return 'text/html';
-            }
-        }
-
-        return 'text/html';
-    }
-}
-
-class_alias('SimplePie\Content\Type\Sniffer', 'SimplePie_Content_Type_Sniffer');
-
-}
-
-namespace SimplePie {
-
-/**
- * Manages `<media:copyright>` copyright tags as defined in Media RSS
- *
- * Used by {@see \SimplePie\Enclosure::get_copyright()}
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_copyright_class()}
- *
- * @package SimplePie
- * @subpackage API
- */
-class Copyright
-{
-    /**
-     * Copyright URL
-     *
-     * @var string
-     * @see get_url()
-     */
-    public $url;
-
-    /**
-     * Attribution
-     *
-     * @var string
-     * @see get_attribution()
-     */
-    public $label;
-
-    /**
-     * Constructor, used to input the data
-     *
-     * For documentation on all the parameters, see the corresponding
-     * properties and their accessors
-     */
-    public function __construct($url = null, $label = null)
-    {
-        $this->url = $url;
-        $this->label = $label;
-    }
-
-    /**
-     * String-ified version
-     *
-     * @return string
-     */
-    public function __toString()
-    {
-        // There is no $this->data here
-        return md5(serialize($this));
-    }
-
-    /**
-     * Get the copyright URL
-     *
-     * @return string|null URL to copyright information
-     */
-    public function get_url()
-    {
-        if ($this->url !== null) {
-            return $this->url;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the attribution text
-     *
-     * @return string|null
-     */
-    public function get_attribution()
-    {
-        if ($this->label !== null) {
-            return $this->label;
-        }
-
-        return null;
-    }
-}
-
-class_alias('SimplePie\Copyright', 'SimplePie_Copyright');
-
-}
-
-namespace SimplePie {
-
-/**
- * Handles `<media:credit>` as defined in Media RSS
- *
- * Used by {@see \SimplePie\Enclosure::get_credit()} and {@see \SimplePie\Enclosure::get_credits()}
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_credit_class()}
- *
- * @package SimplePie
- * @subpackage API
- */
-class Credit
-{
-    /**
-     * Credited role
-     *
-     * @var string
-     * @see get_role()
-     */
-    public $role;
-
-    /**
-     * Organizational scheme
-     *
-     * @var string
-     * @see get_scheme()
-     */
-    public $scheme;
-
-    /**
-     * Credited name
-     *
-     * @var string
-     * @see get_name()
-     */
-    public $name;
-
-    /**
-     * Constructor, used to input the data
-     *
-     * For documentation on all the parameters, see the corresponding
-     * properties and their accessors
-     */
-    public function __construct($role = null, $scheme = null, $name = null)
-    {
-        $this->role = $role;
-        $this->scheme = $scheme;
-        $this->name = $name;
-    }
-
-    /**
-     * String-ified version
-     *
-     * @return string
-     */
-    public function __toString()
-    {
-        // There is no $this->data here
-        return md5(serialize($this));
-    }
-
-    /**
-     * Get the role of the person receiving credit
-     *
-     * @return string|null
-     */
-    public function get_role()
-    {
-        if ($this->role !== null) {
-            return $this->role;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the organizational scheme
-     *
-     * @return string|null
-     */
-    public function get_scheme()
-    {
-        if ($this->scheme !== null) {
-            return $this->scheme;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the credited person/entity's name
-     *
-     * @return string|null
-     */
-    public function get_name()
-    {
-        if ($this->name !== null) {
-            return $this->name;
-        }
-
-        return null;
-    }
-}
-
-class_alias('SimplePie\Credit', 'SimplePie_Credit');
-
-}
-
-namespace SimplePie {
-
-/**
- * Handles everything related to enclosures (including Media RSS and iTunes RSS)
- *
- * Used by {@see \SimplePie\Item::get_enclosure()} and {@see \SimplePie\Item::get_enclosures()}
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_enclosure_class()}
- *
- * @package SimplePie
- * @subpackage API
- */
-class Enclosure
-{
-    /**
-     * @var string
-     * @see get_bitrate()
-     */
-    public $bitrate;
-
-    /**
-     * @var array
-     * @see get_captions()
-     */
-    public $captions;
-
-    /**
-     * @var array
-     * @see get_categories()
-     */
-    public $categories;
-
-    /**
-     * @var int
-     * @see get_channels()
-     */
-    public $channels;
-
-    /**
-     * @var \SimplePie\Copyright
-     * @see get_copyright()
-     */
-    public $copyright;
-
-    /**
-     * @var array
-     * @see get_credits()
-     */
-    public $credits;
-
-    /**
-     * @var string
-     * @see get_description()
-     */
-    public $description;
-
-    /**
-     * @var int
-     * @see get_duration()
-     */
-    public $duration;
-
-    /**
-     * @var string
-     * @see get_expression()
-     */
-    public $expression;
-
-    /**
-     * @var string
-     * @see get_framerate()
-     */
-    public $framerate;
-
-    /**
-     * @var string
-     * @see get_handler()
-     */
-    public $handler;
-
-    /**
-     * @var array
-     * @see get_hashes()
-     */
-    public $hashes;
-
-    /**
-     * @var string
-     * @see get_height()
-     */
-    public $height;
-
-    /**
-     * @deprecated
-     * @var null
-     */
-    public $javascript;
-
-    /**
-     * @var array
-     * @see get_keywords()
-     */
-    public $keywords;
-
-    /**
-     * @var string
-     * @see get_language()
-     */
-    public $lang;
-
-    /**
-     * @var string
-     * @see get_length()
-     */
-    public $length;
-
-    /**
-     * @var string
-     * @see get_link()
-     */
-    public $link;
-
-    /**
-     * @var string
-     * @see get_medium()
-     */
-    public $medium;
-
-    /**
-     * @var string
-     * @see get_player()
-     */
-    public $player;
-
-    /**
-     * @var array
-     * @see get_ratings()
-     */
-    public $ratings;
-
-    /**
-     * @var array
-     * @see get_restrictions()
-     */
-    public $restrictions;
-
-    /**
-     * @var string
-     * @see get_sampling_rate()
-     */
-    public $samplingrate;
-
-    /**
-     * @var array
-     * @see get_thumbnails()
-     */
-    public $thumbnails;
-
-    /**
-     * @var string
-     * @see get_title()
-     */
-    public $title;
-
-    /**
-     * @var string
-     * @see get_type()
-     */
-    public $type;
-
-    /**
-     * @var string
-     * @see get_width()
-     */
-    public $width;
-
-    /**
-     * Constructor, used to input the data
-     *
-     * For documentation on all the parameters, see the corresponding
-     * properties and their accessors
-     *
-     * @uses idna_convert If available, this will convert an IDN
-     */
-    public function __construct($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)
-    {
-        $this->bitrate = $bitrate;
-        $this->captions = $captions;
-        $this->categories = $categories;
-        $this->channels = $channels;
-        $this->copyright = $copyright;
-        $this->credits = $credits;
-        $this->description = $description;
-        $this->duration = $duration;
-        $this->expression = $expression;
-        $this->framerate = $framerate;
-        $this->hashes = $hashes;
-        $this->height = $height;
-        $this->keywords = $keywords;
-        $this->lang = $lang;
-        $this->length = $length;
-        $this->link = $link;
-        $this->medium = $medium;
-        $this->player = $player;
-        $this->ratings = $ratings;
-        $this->restrictions = $restrictions;
-        $this->samplingrate = $samplingrate;
-        $this->thumbnails = $thumbnails;
-        $this->title = $title;
-        $this->type = $type;
-        $this->width = $width;
-
-        if (class_exists('idna_convert')) {
-            $idn = new \idna_convert();
-            $parsed = \SimplePie\Misc::parse_url($link);
-            $this->link = \SimplePie\Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
-        }
-        $this->handler = $this->get_handler(); // Needs to load last
-    }
-
-    /**
-     * String-ified version
-     *
-     * @return string
-     */
-    public function __toString()
-    {
-        // There is no $this->data here
-        return md5(serialize($this));
-    }
-
-    /**
-     * Get the bitrate
-     *
-     * @return string|null
-     */
-    public function get_bitrate()
-    {
-        if ($this->bitrate !== null) {
-            return $this->bitrate;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a single caption
-     *
-     * @param int $key
-     * @return \SimplePie\Caption|null
-     */
-    public function get_caption($key = 0)
-    {
-        $captions = $this->get_captions();
-        if (isset($captions[$key])) {
-            return $captions[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all captions
-     *
-     * @return array|null Array of {@see \SimplePie\Caption} objects
-     */
-    public function get_captions()
-    {
-        if ($this->captions !== null) {
-            return $this->captions;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a single category
-     *
-     * @param int $key
-     * @return \SimplePie\Category|null
-     */
-    public function get_category($key = 0)
-    {
-        $categories = $this->get_categories();
-        if (isset($categories[$key])) {
-            return $categories[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all categories
-     *
-     * @return array|null Array of {@see \SimplePie\Category} objects
-     */
-    public function get_categories()
-    {
-        if ($this->categories !== null) {
-            return $this->categories;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the number of audio channels
-     *
-     * @return int|null
-     */
-    public function get_channels()
-    {
-        if ($this->channels !== null) {
-            return $this->channels;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the copyright information
-     *
-     * @return \SimplePie\Copyright|null
-     */
-    public function get_copyright()
-    {
-        if ($this->copyright !== null) {
-            return $this->copyright;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a single credit
-     *
-     * @param int $key
-     * @return \SimplePie\Credit|null
-     */
-    public function get_credit($key = 0)
-    {
-        $credits = $this->get_credits();
-        if (isset($credits[$key])) {
-            return $credits[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all credits
-     *
-     * @return array|null Array of {@see \SimplePie\Credit} objects
-     */
-    public function get_credits()
-    {
-        if ($this->credits !== null) {
-            return $this->credits;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the description of the enclosure
-     *
-     * @return string|null
-     */
-    public function get_description()
-    {
-        if ($this->description !== null) {
-            return $this->description;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the duration of the enclosure
-     *
-     * @param bool $convert Convert seconds into hh:mm:ss
-     * @return string|int|null 'hh:mm:ss' string if `$convert` was specified, otherwise integer (or null if none found)
-     */
-    public function get_duration($convert = false)
-    {
-        if ($this->duration !== null) {
-            if ($convert) {
-                $time = \SimplePie\Misc::time_hms($this->duration);
-                return $time;
-            }
-
-            return $this->duration;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the expression
-     *
-     * @return string Probably one of 'sample', 'full', 'nonstop', 'clip'. Defaults to 'full'
-     */
-    public function get_expression()
-    {
-        if ($this->expression !== null) {
-            return $this->expression;
-        }
-
-        return 'full';
-    }
-
-    /**
-     * Get the file extension
-     *
-     * @return string|null
-     */
-    public function get_extension()
-    {
-        if ($this->link !== null) {
-            $url = \SimplePie\Misc::parse_url($this->link);
-            if ($url['path'] !== '') {
-                return pathinfo($url['path'], PATHINFO_EXTENSION);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Get the framerate (in frames-per-second)
-     *
-     * @return string|null
-     */
-    public function get_framerate()
-    {
-        if ($this->framerate !== null) {
-            return $this->framerate;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the preferred handler
-     *
-     * @return string|null One of 'flash', 'fmedia', 'quicktime', 'wmedia', 'mp3'
-     */
-    public function get_handler()
-    {
-        return $this->get_real_type(true);
-    }
-
-    /**
-     * Get a single hash
-     *
-     * @link http://www.rssboard.org/media-rss#media-hash
-     * @param int $key
-     * @return string|null Hash as per `media:hash`, prefixed with "$algo:"
-     */
-    public function get_hash($key = 0)
-    {
-        $hashes = $this->get_hashes();
-        if (isset($hashes[$key])) {
-            return $hashes[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all credits
-     *
-     * @return array|null Array of strings, see {@see get_hash()}
-     */
-    public function get_hashes()
-    {
-        if ($this->hashes !== null) {
-            return $this->hashes;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the height
-     *
-     * @return string|null
-     */
-    public function get_height()
-    {
-        if ($this->height !== null) {
-            return $this->height;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the language
-     *
-     * @link http://tools.ietf.org/html/rfc3066
-     * @return string|null Language code as per RFC 3066
-     */
-    public function get_language()
-    {
-        if ($this->lang !== null) {
-            return $this->lang;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a single keyword
-     *
-     * @param int $key
-     * @return string|null
-     */
-    public function get_keyword($key = 0)
-    {
-        $keywords = $this->get_keywords();
-        if (isset($keywords[$key])) {
-            return $keywords[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all keywords
-     *
-     * @return array|null Array of strings
-     */
-    public function get_keywords()
-    {
-        if ($this->keywords !== null) {
-            return $this->keywords;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get length
-     *
-     * @return float Length in bytes
-     */
-    public function get_length()
-    {
-        if ($this->length !== null) {
-            return $this->length;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the URL
-     *
-     * @return string|null
-     */
-    public function get_link()
-    {
-        if ($this->link !== null) {
-            return $this->link;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the medium
-     *
-     * @link http://www.rssboard.org/media-rss#media-content
-     * @return string|null Should be one of 'image', 'audio', 'video', 'document', 'executable'
-     */
-    public function get_medium()
-    {
-        if ($this->medium !== null) {
-            return $this->medium;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the player URL
-     *
-     * Typically the same as {@see get_permalink()}
-     * @return string|null Player URL
-     */
-    public function get_player()
-    {
-        if ($this->player !== null) {
-            return $this->player;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a single rating
-     *
-     * @param int $key
-     * @return \SimplePie\Rating|null
-     */
-    public function get_rating($key = 0)
-    {
-        $ratings = $this->get_ratings();
-        if (isset($ratings[$key])) {
-            return $ratings[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all ratings
-     *
-     * @return array|null Array of {@see \SimplePie\Rating} objects
-     */
-    public function get_ratings()
-    {
-        if ($this->ratings !== null) {
-            return $this->ratings;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a single restriction
-     *
-     * @param int $key
-     * @return \SimplePie\Restriction|null
-     */
-    public function get_restriction($key = 0)
-    {
-        $restrictions = $this->get_restrictions();
-        if (isset($restrictions[$key])) {
-            return $restrictions[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all restrictions
-     *
-     * @return array|null Array of {@see \SimplePie\Restriction} objects
-     */
-    public function get_restrictions()
-    {
-        if ($this->restrictions !== null) {
-            return $this->restrictions;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the sampling rate (in kHz)
-     *
-     * @return string|null
-     */
-    public function get_sampling_rate()
-    {
-        if ($this->samplingrate !== null) {
-            return $this->samplingrate;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the file size (in MiB)
-     *
-     * @return float|null File size in mebibytes (1048 bytes)
-     */
-    public function get_size()
-    {
-        $length = $this->get_length();
-        if ($length !== null) {
-            return round($length/1048576, 2);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a single thumbnail
-     *
-     * @param int $key
-     * @return string|null Thumbnail URL
-     */
-    public function get_thumbnail($key = 0)
-    {
-        $thumbnails = $this->get_thumbnails();
-        if (isset($thumbnails[$key])) {
-            return $thumbnails[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all thumbnails
-     *
-     * @return array|null Array of thumbnail URLs
-     */
-    public function get_thumbnails()
-    {
-        if ($this->thumbnails !== null) {
-            return $this->thumbnails;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the title
-     *
-     * @return string|null
-     */
-    public function get_title()
-    {
-        if ($this->title !== null) {
-            return $this->title;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get mimetype of the enclosure
-     *
-     * @see get_real_type()
-     * @return string|null MIME type
-     */
-    public function get_type()
-    {
-        if ($this->type !== null) {
-            return $this->type;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the width
-     *
-     * @return string|null
-     */
-    public function get_width()
-    {
-        if ($this->width !== null) {
-            return $this->width;
-        }
-
-        return null;
-    }
-
-    /**
-     * Embed the enclosure using `<embed>`
-     *
-     * @deprecated Use the second parameter to {@see embed} instead
-     *
-     * @param array|string $options See first parameter to {@see embed}
-     * @return string HTML string to output
-     */
-    public function native_embed($options='')
-    {
-        return $this->embed($options, true);
-    }
-
-    /**
-     * Embed the enclosure using Javascript
-     *
-     * `$options` is an array or comma-separated key:value string, with the
-     * following properties:
-     *
-     * - `alt` (string): Alternate content for when an end-user does not have
-     *    the appropriate handler installed or when a file type is
-     *    unsupported. Can be any text or HTML. Defaults to blank.
-     * - `altclass` (string): If a file type is unsupported, the end-user will
-     *    see the alt text (above) linked directly to the content. That link
-     *    will have this value as its class name. Defaults to blank.
-     * - `audio` (string): This is an image that should be used as a
-     *    placeholder for audio files before they're loaded (QuickTime-only).
-     *    Can be any relative or absolute URL. Defaults to blank.
-     * - `bgcolor` (string): The background color for the media, if not
-     *    already transparent. Defaults to `#ffffff`.
-     * - `height` (integer): The height of the embedded media. Accepts any
-     *    numeric pixel value (such as `360`) or `auto`. Defaults to `auto`,
-     *    and it is recommended that you use this default.
-     * - `loop` (boolean): Do you want the media to loop when it's done?
-     *    Defaults to `false`.
-     * - `mediaplayer` (string): The location of the included
-     *    `mediaplayer.swf` file. This allows for the playback of Flash Video
-     *    (`.flv`) files, and is the default handler for non-Odeo MP3's.
-     *    Defaults to blank.
-     * - `video` (string): This is an image that should be used as a
-     *    placeholder for video files before they're loaded (QuickTime-only).
-     *    Can be any relative or absolute URL. Defaults to blank.
-     * - `width` (integer): The width of the embedded media. Accepts any
-     *    numeric pixel value (such as `480`) or `auto`. Defaults to `auto`,
-     *    and it is recommended that you use this default.
-     * - `widescreen` (boolean): Is the enclosure widescreen or standard?
-     *    This applies only to video enclosures, and will automatically resize
-     *    the content appropriately.  Defaults to `false`, implying 4:3 mode.
-     *
-     * Note: Non-widescreen (4:3) mode with `width` and `height` set to `auto`
-     * will default to 480x360 video resolution.  Widescreen (16:9) mode with
-     * `width` and `height` set to `auto` will default to 480x270 video resolution.
-     *
-     * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
-     * @param array|string $options Comma-separated key:value list, or array
-     * @param bool $native Use `<embed>`
-     * @return string HTML string to output
-     */
-    public function embed($options = '', $native = false)
-    {
-        // Set up defaults
-        $audio = '';
-        $video = '';
-        $alt = '';
-        $altclass = '';
-        $loop = 'false';
-        $width = 'auto';
-        $height = 'auto';
-        $bgcolor = '#ffffff';
-        $mediaplayer = '';
-        $widescreen = false;
-        $handler = $this->get_handler();
-        $type = $this->get_real_type();
-        $placeholder = '';
-
-        // Process options and reassign values as necessary
-        if (is_array($options)) {
-            extract($options);
-        } else {
-            $options = explode(',', $options);
-            foreach ($options as $option) {
-                $opt = explode(':', $option, 2);
-                if (isset($opt[0], $opt[1])) {
-                    $opt[0] = trim($opt[0]);
-                    $opt[1] = trim($opt[1]);
-                    switch ($opt[0]) {
-                        case 'audio':
-                            $audio = $opt[1];
-                            break;
-
-                        case 'video':
-                            $video = $opt[1];
-                            break;
-
-                        case 'alt':
-                            $alt = $opt[1];
-                            break;
-
-                        case 'altclass':
-                            $altclass = $opt[1];
-                            break;
-
-                        case 'loop':
-                            $loop = $opt[1];
-                            break;
-
-                        case 'width':
-                            $width = $opt[1];
-                            break;
-
-                        case 'height':
-                            $height = $opt[1];
-                            break;
-
-                        case 'bgcolor':
-                            $bgcolor = $opt[1];
-                            break;
-
-                        case 'mediaplayer':
-                            $mediaplayer = $opt[1];
-                            break;
-
-                        case 'widescreen':
-                            $widescreen = $opt[1];
-                            break;
-                    }
-                }
-            }
-        }
-
-        $mime = explode('/', $type, 2);
-        $mime = $mime[0];
-
-        // Process values for 'auto'
-        if ($width === 'auto') {
-            if ($mime === 'video') {
-                if ($height === 'auto') {
-                    $width = 480;
-                } elseif ($widescreen) {
-                    $width = round((intval($height)/9)*16);
-                } else {
-                    $width = round((intval($height)/3)*4);
-                }
-            } else {
-                $width = '100%';
-            }
-        }
-
-        if ($height === 'auto') {
-            if ($mime === 'audio') {
-                $height = 0;
-            } elseif ($mime === 'video') {
-                if ($width === 'auto') {
-                    if ($widescreen) {
-                        $height = 270;
-                    } else {
-                        $height = 360;
-                    }
-                } elseif ($widescreen) {
-                    $height = round((intval($width)/16)*9);
-                } else {
-                    $height = round((intval($width)/4)*3);
-                }
-            } else {
-                $height = 376;
-            }
-        } elseif ($mime === 'audio') {
-            $height = 0;
-        }
-
-        // Set proper placeholder value
-        if ($mime === 'audio') {
-            $placeholder = $audio;
-        } elseif ($mime === 'video') {
-            $placeholder = $video;
-        }
-
-        $embed = '';
-
-        // Flash
-        if ($handler === 'flash') {
-            if ($native) {
-                $embed .= "<embed src=\"" . $this->get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\"></embed>";
-            } else {
-                $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
-            }
-        }
-
-        // Flash Media Player file types.
-        // Preferred handler for MP3 file types.
-        elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== '')) {
-            $height += 20;
-            if ($native) {
-                $embed .= "<embed src=\"$mediaplayer\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" quality=\"high\" width=\"$width\" height=\"$height\" wmode=\"transparent\" flashvars=\"file=" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\"></embed>";
-            } else {
-                $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
-            }
-        }
-
-        // QuickTime 7 file types.  Need to test with QuickTime 6.
-        // Only handle MP3's if the Flash Media Player is not present.
-        elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === '')) {
-            $height += 16;
-            if ($native) {
-                if ($placeholder !== '') {
-                    $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" href=\"" . $this->get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
-                } else {
-                    $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" src=\"" . $this->get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
-                }
-            } else {
-                $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
-            }
-        }
-
-        // Windows Media
-        elseif ($handler === 'wmedia') {
-            $height += 45;
-            if ($native) {
-                $embed .= "<embed type=\"application/x-mplayer2\" src=\"" . $this->get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\"></embed>";
-            } else {
-                $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
-            }
-        }
-
-        // Everything else
-        else {
-            $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
-        }
-
-        return $embed;
-    }
-
-    /**
-     * Get the real media type
-     *
-     * Often, feeds lie to us, necessitating a bit of deeper inspection. This
-     * converts types to their canonical representations based on the file
-     * extension
-     *
-     * @see get_type()
-     * @param bool $find_handler Internal use only, use {@see get_handler()} instead
-     * @return string MIME type
-     */
-    public function get_real_type($find_handler = false)
-    {
-        // Mime-types by handler.
-        $types_flash = ['application/x-shockwave-flash', 'application/futuresplash']; // Flash
-        $types_fmedia = ['video/flv', 'video/x-flv','flv-application/octet-stream']; // Flash Media Player
-        $types_quicktime = ['audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video']; // QuickTime
-        $types_wmedia = ['application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx']; // Windows Media
-        $types_mp3 = ['audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg']; // MP3
-
-        if ($this->get_type() !== null) {
-            $type = strtolower($this->type);
-        } else {
-            $type = null;
-        }
-
-        // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
-        if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3))) {
-            $extension = $this->get_extension();
-            if ($extension === null) {
-                return null;
-            }
-
-            switch (strtolower($extension)) {
-                // Audio mime-types
-                case 'aac':
-                case 'adts':
-                    $type = 'audio/acc';
-                    break;
-
-                case 'aif':
-                case 'aifc':
-                case 'aiff':
-                case 'cdda':
-                    $type = 'audio/aiff';
-                    break;
-
-                case 'bwf':
-                    $type = 'audio/wav';
-                    break;
-
-                case 'kar':
-                case 'mid':
-                case 'midi':
-                case 'smf':
-                    $type = 'audio/midi';
-                    break;
-
-                case 'm4a':
-                    $type = 'audio/x-m4a';
-                    break;
-
-                case 'mp3':
-                case 'swa':
-                    $type = 'audio/mp3';
-                    break;
-
-                case 'wav':
-                    $type = 'audio/wav';
-                    break;
-
-                case 'wax':
-                    $type = 'audio/x-ms-wax';
-                    break;
-
-                case 'wma':
-                    $type = 'audio/x-ms-wma';
-                    break;
-
-                // Video mime-types
-                case '3gp':
-                case '3gpp':
-                    $type = 'video/3gpp';
-                    break;
-
-                case '3g2':
-                case '3gp2':
-                    $type = 'video/3gpp2';
-                    break;
-
-                case 'asf':
-                    $type = 'video/x-ms-asf';
-                    break;
-
-                case 'flv':
-                    $type = 'video/x-flv';
-                    break;
-
-                case 'm1a':
-                case 'm1s':
-                case 'm1v':
-                case 'm15':
-                case 'm75':
-                case 'mp2':
-                case 'mpa':
-                case 'mpeg':
-                case 'mpg':
-                case 'mpm':
-                case 'mpv':
-                    $type = 'video/mpeg';
-                    break;
-
-                case 'm4v':
-                    $type = 'video/x-m4v';
-                    break;
-
-                case 'mov':
-                case 'qt':
-                    $type = 'video/quicktime';
-                    break;
-
-                case 'mp4':
-                case 'mpg4':
-                    $type = 'video/mp4';
-                    break;
-
-                case 'sdv':
-                    $type = 'video/sd-video';
-                    break;
-
-                case 'wm':
-                    $type = 'video/x-ms-wm';
-                    break;
-
-                case 'wmv':
-                    $type = 'video/x-ms-wmv';
-                    break;
-
-                case 'wvx':
-                    $type = 'video/x-ms-wvx';
-                    break;
-
-                // Flash mime-types
-                case 'spl':
-                    $type = 'application/futuresplash';
-                    break;
-
-                case 'swf':
-                    $type = 'application/x-shockwave-flash';
-                    break;
-            }
-        }
-
-        if ($find_handler) {
-            if (in_array($type, $types_flash)) {
-                return 'flash';
-            } elseif (in_array($type, $types_fmedia)) {
-                return 'fmedia';
-            } elseif (in_array($type, $types_quicktime)) {
-                return 'quicktime';
-            } elseif (in_array($type, $types_wmedia)) {
-                return 'wmedia';
-            } elseif (in_array($type, $types_mp3)) {
-                return 'mp3';
-            }
-
-            return null;
-        }
-
-        return $type;
-    }
-}
-
-class_alias('SimplePie\Enclosure', 'SimplePie_Enclosure');
-
-}
-
-namespace SimplePie {
-
-use Exception as NativeException;
-
-/**
- * General SimplePie exception class
- *
- * @package SimplePie
- */
-class Exception extends NativeException
-{
-}
-
-class_alias('SimplePie\Exception', 'SimplePie_Exception');
-
-}
-
-namespace SimplePie {
-
-/**
- * Used for fetching remote files and reading local files
- *
- * Supports HTTP 1.0 via cURL or fsockopen, with spotty HTTP 1.1 support
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_file_class()}
- *
- * @package SimplePie
- * @subpackage HTTP
- * @todo Move to properly supporting RFC2616 (HTTP/1.1)
- */
-class File
-{
-    public $url;
-    public $useragent;
-    public $success = true;
-    public $headers = [];
-    public $body;
-    public $status_code = 0;
-    public $redirects = 0;
-    public $error;
-    public $method = \SimplePie\SimplePie::FILE_SOURCE_NONE;
-    public $permanent_url;
-
-    public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false, $curl_options = [])
-    {
-        if (class_exists('idna_convert')) {
-            $idn = new \idna_convert();
-            $parsed = \SimplePie\Misc::parse_url($url);
-            $url = \SimplePie\Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], null);
-        }
-        $this->url = $url;
-        $this->permanent_url = $url;
-        $this->useragent = $useragent;
-        if (preg_match('/^http(s)?:\/\//i', $url)) {
-            if ($useragent === null) {
-                $useragent = ini_get('user_agent');
-                $this->useragent = $useragent;
-            }
-            if (!is_array($headers)) {
-                $headers = [];
-            }
-            if (!$force_fsockopen && function_exists('curl_exec')) {
-                $this->method = \SimplePie\SimplePie::FILE_SOURCE_REMOTE | \SimplePie\SimplePie::FILE_SOURCE_CURL;
-                $fp = curl_init();
-                $headers2 = [];
-                foreach ($headers as $key => $value) {
-                    $headers2[] = "$key: $value";
-                }
-                if (version_compare(\SimplePie\Misc::get_curl_version(), '7.10.5', '>=')) {
-                    curl_setopt($fp, CURLOPT_ENCODING, '');
-                }
-                curl_setopt($fp, CURLOPT_URL, $url);
-                curl_setopt($fp, CURLOPT_HEADER, 1);
-                curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
-                curl_setopt($fp, CURLOPT_FAILONERROR, 1);
-                curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
-                curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
-                curl_setopt($fp, CURLOPT_REFERER, \SimplePie\Misc::url_remove_credentials($url));
-                curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
-                curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
-                foreach ($curl_options as $curl_param => $curl_value) {
-                    curl_setopt($fp, $curl_param, $curl_value);
-                }
-
-                $this->headers = curl_exec($fp);
-                if (curl_errno($fp) === 23 || curl_errno($fp) === 61) {
-                    curl_setopt($fp, CURLOPT_ENCODING, 'none');
-                    $this->headers = curl_exec($fp);
-                }
-                $this->status_code = curl_getinfo($fp, CURLINFO_HTTP_CODE);
-                if (curl_errno($fp)) {
-                    $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
-                    $this->success = false;
-                } else {
-                    // Use the updated url provided by curl_getinfo after any redirects.
-                    if ($info = curl_getinfo($fp)) {
-                        $this->url = $info['url'];
-                    }
-                    curl_close($fp);
-                    $this->headers = \SimplePie\HTTP\Parser::prepareHeaders($this->headers, $info['redirect_count'] + 1);
-                    $parser = new \SimplePie\HTTP\Parser($this->headers);
-                    if ($parser->parse()) {
-                        $this->headers = $parser->headers;
-                        $this->body = trim($parser->body);
-                        $this->status_code = $parser->status_code;
-                        if ((in_array($this->status_code, [300, 301, 302, 303, 307]) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) {
-                            $this->redirects++;
-                            $location = \SimplePie\Misc::absolutize_url($this->headers['location'], $url);
-                            $previousStatusCode = $this->status_code;
-                            $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen, $curl_options);
-                            $this->permanent_url = ($previousStatusCode == 301) ? $location : $url;
-                            return;
-                        }
-                    }
-                }
-            } else {
-                $this->method = \SimplePie\SimplePie::FILE_SOURCE_REMOTE | \SimplePie\SimplePie::FILE_SOURCE_FSOCKOPEN;
-                $url_parts = parse_url($url);
-                $socket_host = $url_parts['host'];
-                if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') {
-                    $socket_host = "ssl://$url_parts[host]";
-                    $url_parts['port'] = 443;
-                }
-                if (!isset($url_parts['port'])) {
-                    $url_parts['port'] = 80;
-                }
-                $fp = @fsockopen($socket_host, $url_parts['port'], $errno, $errstr, $timeout);
-                if (!$fp) {
-                    $this->error = 'fsockopen error: ' . $errstr;
-                    $this->success = false;
-                } else {
-                    stream_set_timeout($fp, $timeout);
-                    if (isset($url_parts['path'])) {
-                        if (isset($url_parts['query'])) {
-                            $get = "$url_parts[path]?$url_parts[query]";
-                        } else {
-                            $get = $url_parts['path'];
-                        }
-                    } else {
-                        $get = '/';
-                    }
-                    $out = "GET $get HTTP/1.1\r\n";
-                    $out .= "Host: $url_parts[host]\r\n";
-                    $out .= "User-Agent: $useragent\r\n";
-                    if (extension_loaded('zlib')) {
-                        $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
-                    }
-
-                    if (isset($url_parts['user']) && isset($url_parts['pass'])) {
-                        $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
-                    }
-                    foreach ($headers as $key => $value) {
-                        $out .= "$key: $value\r\n";
-                    }
-                    $out .= "Connection: Close\r\n\r\n";
-                    fwrite($fp, $out);
-
-                    $info = stream_get_meta_data($fp);
-
-                    $this->headers = '';
-                    while (!$info['eof'] && !$info['timed_out']) {
-                        $this->headers .= fread($fp, 1160);
-                        $info = stream_get_meta_data($fp);
-                    }
-                    if (!$info['timed_out']) {
-                        $parser = new \SimplePie\HTTP\Parser($this->headers);
-                        if ($parser->parse()) {
-                            $this->headers = $parser->headers;
-                            $this->body = $parser->body;
-                            $this->status_code = $parser->status_code;
-                            if ((in_array($this->status_code, [300, 301, 302, 303, 307]) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) {
-                                $this->redirects++;
-                                $location = \SimplePie\Misc::absolutize_url($this->headers['location'], $url);
-                                $previousStatusCode = $this->status_code;
-                                $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen, $curl_options);
-                                $this->permanent_url = ($previousStatusCode == 301) ? $location : $url;
-                                return;
-                            }
-                            if (isset($this->headers['content-encoding'])) {
-                                // Hey, we act dumb elsewhere, so let's do that here too
-                                switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20"))) {
-                                    case 'gzip':
-                                    case 'x-gzip':
-                                        $decoder = new \SimplePie\Gzdecode($this->body);
-                                        if (!$decoder->parse()) {
-                                            $this->error = 'Unable to decode HTTP "gzip" stream';
-                                            $this->success = false;
-                                        } else {
-                                            $this->body = trim($decoder->data);
-                                        }
-                                        break;
-
-                                    case 'deflate':
-                                        if (($decompressed = gzinflate($this->body)) !== false) {
-                                            $this->body = $decompressed;
-                                        } elseif (($decompressed = gzuncompress($this->body)) !== false) {
-                                            $this->body = $decompressed;
-                                        } elseif (function_exists('gzdecode') && ($decompressed = gzdecode($this->body)) !== false) {
-                                            $this->body = $decompressed;
-                                        } else {
-                                            $this->error = 'Unable to decode HTTP "deflate" stream';
-                                            $this->success = false;
-                                        }
-                                        break;
-
-                                    default:
-                                        $this->error = 'Unknown content coding';
-                                        $this->success = false;
-                                }
-                            }
-                        }
-                    } else {
-                        $this->error = 'fsocket timed out';
-                        $this->success = false;
-                    }
-                    fclose($fp);
-                }
-            }
-        } else {
-            $this->method = \SimplePie\SimplePie::FILE_SOURCE_LOCAL | \SimplePie\SimplePie::FILE_SOURCE_FILE_GET_CONTENTS;
-            if (empty($url) || !($this->body = trim(file_get_contents($url)))) {
-                $this->error = 'file_get_contents could not read the file';
-                $this->success = false;
-            }
-        }
-    }
-}
-
-class_alias('SimplePie\File', 'SimplePie_File');
-
-}
-
-namespace SimplePie {
-
-/**
- * Decode 'gzip' encoded HTTP data
- *
- * @package SimplePie
- * @subpackage HTTP
- * @link http://www.gzip.org/format.txt
- */
-class Gzdecode
-{
-    /**
-     * Compressed data
-     *
-     * @access private
-     * @var string
-     * @see gzdecode::$data
-     */
-    public $compressed_data;
-
-    /**
-     * Size of compressed data
-     *
-     * @access private
-     * @var int
-     */
-    public $compressed_size;
-
-    /**
-     * Minimum size of a valid gzip string
-     *
-     * @access private
-     * @var int
-     */
-    public $min_compressed_size = 18;
-
-    /**
-     * Current position of pointer
-     *
-     * @access private
-     * @var int
-     */
-    public $position = 0;
-
-    /**
-     * Flags (FLG)
-     *
-     * @access private
-     * @var int
-     */
-    public $flags;
-
-    /**
-     * Uncompressed data
-     *
-     * @access public
-     * @see gzdecode::$compressed_data
-     * @var string
-     */
-    public $data;
-
-    /**
-     * Modified time
-     *
-     * @access public
-     * @var int
-     */
-    public $MTIME;
-
-    /**
-     * Extra Flags
-     *
-     * @access public
-     * @var int
-     */
-    public $XFL;
-
-    /**
-     * Operating System
-     *
-     * @access public
-     * @var int
-     */
-    public $OS;
-
-    /**
-     * Subfield ID 1
-     *
-     * @access public
-     * @see gzdecode::$extra_field
-     * @see gzdecode::$SI2
-     * @var string
-     */
-    public $SI1;
-
-    /**
-     * Subfield ID 2
-     *
-     * @access public
-     * @see gzdecode::$extra_field
-     * @see gzdecode::$SI1
-     * @var string
-     */
-    public $SI2;
-
-    /**
-     * Extra field content
-     *
-     * @access public
-     * @see gzdecode::$SI1
-     * @see gzdecode::$SI2
-     * @var string
-     */
-    public $extra_field;
-
-    /**
-     * Original filename
-     *
-     * @access public
-     * @var string
-     */
-    public $filename;
-
-    /**
-     * Human readable comment
-     *
-     * @access public
-     * @var string
-     */
-    public $comment;
-
-    /**
-     * Don't allow anything to be set
-     *
-     * @param string $name
-     * @param mixed $value
-     */
-    public function __set($name, $value)
-    {
-        trigger_error("Cannot write property $name", E_USER_ERROR);
-    }
-
-    /**
-     * Set the compressed string and related properties
-     *
-     * @param string $data
-     */
-    public function __construct($data)
-    {
-        $this->compressed_data = $data;
-        $this->compressed_size = strlen($data);
-    }
-
-    /**
-     * Decode the GZIP stream
-     *
-     * @return bool Successfulness
-     */
-    public function parse()
-    {
-        if ($this->compressed_size >= $this->min_compressed_size) {
-            $len = 0;
-
-            // Check ID1, ID2, and CM
-            if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08") {
-                return false;
-            }
-
-            // Get the FLG (FLaGs)
-            $this->flags = ord($this->compressed_data[3]);
-
-            // FLG bits above (1 << 4) are reserved
-            if ($this->flags > 0x1F) {
-                return false;
-            }
-
-            // Advance the pointer after the above
-            $this->position += 4;
-
-            // MTIME
-            $mtime = substr($this->compressed_data, $this->position, 4);
-            // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
-            if (current(unpack('S', "\x00\x01")) === 1) {
-                $mtime = strrev($mtime);
-            }
-            $this->MTIME = current(unpack('l', $mtime));
-            $this->position += 4;
-
-            // Get the XFL (eXtra FLags)
-            $this->XFL = ord($this->compressed_data[$this->position++]);
-
-            // Get the OS (Operating System)
-            $this->OS = ord($this->compressed_data[$this->position++]);
-
-            // Parse the FEXTRA
-            if ($this->flags & 4) {
-                // Read subfield IDs
-                $this->SI1 = $this->compressed_data[$this->position++];
-                $this->SI2 = $this->compressed_data[$this->position++];
-
-                // SI2 set to zero is reserved for future use
-                if ($this->SI2 === "\x00") {
-                    return false;
-                }
-
-                // Get the length of the extra field
-                $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
-                $this->position += 2;
-
-                // Check the length of the string is still valid
-                $this->min_compressed_size += $len + 4;
-                if ($this->compressed_size >= $this->min_compressed_size) {
-                    // Set the extra field to the given data
-                    $this->extra_field = substr($this->compressed_data, $this->position, $len);
-                    $this->position += $len;
-                } else {
-                    return false;
-                }
-            }
-
-            // Parse the FNAME
-            if ($this->flags & 8) {
-                // Get the length of the filename
-                $len = strcspn($this->compressed_data, "\x00", $this->position);
-
-                // Check the length of the string is still valid
-                $this->min_compressed_size += $len + 1;
-                if ($this->compressed_size >= $this->min_compressed_size) {
-                    // Set the original filename to the given string
-                    $this->filename = substr($this->compressed_data, $this->position, $len);
-                    $this->position += $len + 1;
-                } else {
-                    return false;
-                }
-            }
-
-            // Parse the FCOMMENT
-            if ($this->flags & 16) {
-                // Get the length of the comment
-                $len = strcspn($this->compressed_data, "\x00", $this->position);
-
-                // Check the length of the string is still valid
-                $this->min_compressed_size += $len + 1;
-                if ($this->compressed_size >= $this->min_compressed_size) {
-                    // Set the original comment to the given string
-                    $this->comment = substr($this->compressed_data, $this->position, $len);
-                    $this->position += $len + 1;
-                } else {
-                    return false;
-                }
-            }
-
-            // Parse the FHCRC
-            if ($this->flags & 2) {
-                // Check the length of the string is still valid
-                $this->min_compressed_size += $len + 2;
-                if ($this->compressed_size >= $this->min_compressed_size) {
-                    // Read the CRC
-                    $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
-
-                    // Check the CRC matches
-                    if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc) {
-                        $this->position += 2;
-                    } else {
-                        return false;
-                    }
-                } else {
-                    return false;
-                }
-            }
-
-            // Decompress the actual data
-            if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false) {
-                return false;
-            }
-
-            $this->position = $this->compressed_size - 8;
-
-            // Check CRC of data
-            $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
-            $this->position += 4;
-            /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
-            {
-                return false;
-            }*/
-
-            // Check ISIZE of data
-            $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
-            $this->position += 4;
-            if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize)) {
-                return false;
-            }
-
-            // Wow, against all odds, we've actually got a valid gzip string
-            return true;
-        }
-
-        return false;
-    }
-}
-
-class_alias('SimplePie\Gzdecode', 'SimplePie_gzdecode');
-
-}
-
-namespace SimplePie\HTTP {
-
-/**
- * HTTP Response Parser
- *
- * @package SimplePie
- * @subpackage HTTP
- */
-class Parser
-{
-    /**
-     * HTTP Version
-     *
-     * @var float
-     */
-    public $http_version = 0.0;
-
-    /**
-     * Status code
-     *
-     * @var int
-     */
-    public $status_code = 0;
-
-    /**
-     * Reason phrase
-     *
-     * @var string
-     */
-    public $reason = '';
-
-    /**
-     * Key/value pairs of the headers
-     *
-     * @var array
-     */
-    public $headers = [];
-
-    /**
-     * Body of the response
-     *
-     * @var string
-     */
-    public $body = '';
-
-    private const STATE_HTTP_VERSION = 'http_version';
-
-    private const STATE_STATUS = 'status';
-
-    private const STATE_REASON = 'reason';
-
-    private const STATE_NEW_LINE = 'new_line';
-
-    private const STATE_BODY = 'body';
-
-    private const STATE_NAME = 'name';
-
-    private const STATE_VALUE = 'value';
-
-    private const STATE_VALUE_CHAR = 'value_char';
-
-    private const STATE_QUOTE = 'quote';
-
-    private const STATE_QUOTE_ESCAPED = 'quote_escaped';
-
-    private const STATE_QUOTE_CHAR = 'quote_char';
-
-    private const STATE_CHUNKED = 'chunked';
-
-    private const STATE_EMIT = 'emit';
-
-    private const STATE_ERROR = false;
-
-    /**
-     * Current state of the state machine
-     *
-     * @var self::STATE_*
-     */
-    protected $state = self::STATE_HTTP_VERSION;
-
-    /**
-     * Input data
-     *
-     * @var string
-     */
-    protected $data = '';
-
-    /**
-     * Input data length (to avoid calling strlen() everytime this is needed)
-     *
-     * @var int
-     */
-    protected $data_length = 0;
-
-    /**
-     * Current position of the pointer
-     *
-     * @var int
-     */
-    protected $position = 0;
-
-    /**
-     * Name of the hedaer currently being parsed
-     *
-     * @var string
-     */
-    protected $name = '';
-
-    /**
-     * Value of the hedaer currently being parsed
-     *
-     * @var string
-     */
-    protected $value = '';
-
-    /**
-     * Create an instance of the class with the input data
-     *
-     * @param string $data Input data
-     */
-    public function __construct($data)
-    {
-        $this->data = $data;
-        $this->data_length = strlen($this->data);
-    }
-
-    /**
-     * Parse the input data
-     *
-     * @return bool true on success, false on failure
-     */
-    public function parse()
-    {
-        while ($this->state && $this->state !== self::STATE_EMIT && $this->has_data()) {
-            $state = $this->state;
-            $this->$state();
-        }
-        $this->data = '';
-        if ($this->state === self::STATE_EMIT || $this->state === self::STATE_BODY) {
-            return true;
-        }
-
-        $this->http_version = '';
-        $this->status_code = 0;
-        $this->reason = '';
-        $this->headers = [];
-        $this->body = '';
-        return false;
-    }
-
-    /**
-     * Check whether there is data beyond the pointer
-     *
-     * @return bool true if there is further data, false if not
-     */
-    protected function has_data()
-    {
-        return (bool) ($this->position < $this->data_length);
-    }
-
-    /**
-     * See if the next character is LWS
-     *
-     * @return bool true if the next character is LWS, false if not
-     */
-    protected function is_linear_whitespace()
-    {
-        return (bool) ($this->data[$this->position] === "\x09"
-            || $this->data[$this->position] === "\x20"
-            || ($this->data[$this->position] === "\x0A"
-                && isset($this->data[$this->position + 1])
-                && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
-    }
-
-    /**
-     * Parse the HTTP version
-     */
-    protected function http_version()
-    {
-        if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/') {
-            $len = strspn($this->data, '0123456789.', 5);
-            $this->http_version = substr($this->data, 5, $len);
-            $this->position += 5 + $len;
-            if (substr_count($this->http_version, '.') <= 1) {
-                $this->http_version = (float) $this->http_version;
-                $this->position += strspn($this->data, "\x09\x20", $this->position);
-                $this->state = self::STATE_STATUS;
-            } else {
-                $this->state = self::STATE_ERROR;
-            }
-        } else {
-            $this->state = self::STATE_ERROR;
-        }
-    }
-
-    /**
-     * Parse the status code
-     */
-    protected function status()
-    {
-        if ($len = strspn($this->data, '0123456789', $this->position)) {
-            $this->status_code = (int) substr($this->data, $this->position, $len);
-            $this->position += $len;
-            $this->state = self::STATE_REASON;
-        } else {
-            $this->state = self::STATE_ERROR;
-        }
-    }
-
-    /**
-     * Parse the reason phrase
-     */
-    protected function reason()
-    {
-        $len = strcspn($this->data, "\x0A", $this->position);
-        $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
-        $this->position += $len + 1;
-        $this->state = self::STATE_NEW_LINE;
-    }
-
-    /**
-     * Deal with a new line, shifting data around as needed
-     */
-    protected function new_line()
-    {
-        $this->value = trim($this->value, "\x0D\x20");
-        if ($this->name !== '' && $this->value !== '') {
-            $this->name = strtolower($this->name);
-            // We should only use the last Content-Type header. c.f. issue #1
-            if (isset($this->headers[$this->name]) && $this->name !== 'content-type') {
-                $this->headers[$this->name] .= ', ' . $this->value;
-            } else {
-                $this->headers[$this->name] = $this->value;
-            }
-        }
-        $this->name = '';
-        $this->value = '';
-        if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A") {
-            $this->position += 2;
-            $this->state = self::STATE_BODY;
-        } elseif ($this->data[$this->position] === "\x0A") {
-            $this->position++;
-            $this->state = self::STATE_BODY;
-        } else {
-            $this->state = self::STATE_NAME;
-        }
-    }
-
-    /**
-     * Parse a header name
-     */
-    protected function name()
-    {
-        $len = strcspn($this->data, "\x0A:", $this->position);
-        if (isset($this->data[$this->position + $len])) {
-            if ($this->data[$this->position + $len] === "\x0A") {
-                $this->position += $len;
-                $this->state = self::STATE_NEW_LINE;
-            } else {
-                $this->name = substr($this->data, $this->position, $len);
-                $this->position += $len + 1;
-                $this->state = self::STATE_VALUE;
-            }
-        } else {
-            $this->state = self::STATE_ERROR;
-        }
-    }
-
-    /**
-     * Parse LWS, replacing consecutive LWS characters with a single space
-     */
-    protected function linear_whitespace()
-    {
-        do {
-            if (substr($this->data, $this->position, 2) === "\x0D\x0A") {
-                $this->position += 2;
-            } elseif ($this->data[$this->position] === "\x0A") {
-                $this->position++;
-            }
-            $this->position += strspn($this->data, "\x09\x20", $this->position);
-        } while ($this->has_data() && $this->is_linear_whitespace());
-        $this->value .= "\x20";
-    }
-
-    /**
-     * See what state to move to while within non-quoted header values
-     */
-    protected function value()
-    {
-        if ($this->is_linear_whitespace()) {
-            $this->linear_whitespace();
-        } else {
-            switch ($this->data[$this->position]) {
-                case '"':
-                    // Workaround for ETags: we have to include the quotes as
-                    // part of the tag.
-                    if (strtolower($this->name) === 'etag') {
-                        $this->value .= '"';
-                        $this->position++;
-                        $this->state = self::STATE_VALUE_CHAR;
-                        break;
-                    }
-                    $this->position++;
-                    $this->state = self::STATE_QUOTE;
-                    break;
-
-                case "\x0A":
-                    $this->position++;
-                    $this->state = self::STATE_NEW_LINE;
-                    break;
-
-                default:
-                    $this->state = self::STATE_VALUE_CHAR;
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Parse a header value while outside quotes
-     */
-    protected function value_char()
-    {
-        $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
-        $this->value .= substr($this->data, $this->position, $len);
-        $this->position += $len;
-        $this->state = self::STATE_VALUE;
-    }
-
-    /**
-     * See what state to move to while within quoted header values
-     */
-    protected function quote()
-    {
-        if ($this->is_linear_whitespace()) {
-            $this->linear_whitespace();
-        } else {
-            switch ($this->data[$this->position]) {
-                case '"':
-                    $this->position++;
-                    $this->state = self::STATE_VALUE;
-                    break;
-
-                case "\x0A":
-                    $this->position++;
-                    $this->state = self::STATE_NEW_LINE;
-                    break;
-
-                case '\\':
-                    $this->position++;
-                    $this->state = self::STATE_QUOTE_ESCAPED;
-                    break;
-
-                default:
-                    $this->state = self::STATE_QUOTE_CHAR;
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Parse a header value while within quotes
-     */
-    protected function quote_char()
-    {
-        $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
-        $this->value .= substr($this->data, $this->position, $len);
-        $this->position += $len;
-        $this->state = self::STATE_VALUE;
-    }
-
-    /**
-     * Parse an escaped character within quotes
-     */
-    protected function quote_escaped()
-    {
-        $this->value .= $this->data[$this->position];
-        $this->position++;
-        $this->state = self::STATE_QUOTE;
-    }
-
-    /**
-     * Parse the body
-     */
-    protected function body()
-    {
-        $this->body = substr($this->data, $this->position);
-        if (!empty($this->headers['transfer-encoding'])) {
-            unset($this->headers['transfer-encoding']);
-            $this->state = self::STATE_CHUNKED;
-        } else {
-            $this->state = self::STATE_EMIT;
-        }
-    }
-
-    /**
-     * Parsed a "Transfer-Encoding: chunked" body
-     */
-    protected function chunked()
-    {
-        if (!preg_match('/^([0-9a-f]+)[^\r\n]*\r\n/i', trim($this->body))) {
-            $this->state = self::STATE_EMIT;
-            return;
-        }
-
-        $decoded = '';
-        $encoded = $this->body;
-
-        while (true) {
-            $is_chunked = (bool) preg_match('/^([0-9a-f]+)[^\r\n]*\r\n/i', $encoded, $matches);
-            if (!$is_chunked) {
-                // Looks like it's not chunked after all
-                $this->state = self::STATE_EMIT;
-                return;
-            }
-
-            $length = hexdec(trim($matches[1]));
-            if ($length === 0) {
-                // Ignore trailer headers
-                $this->state = self::STATE_EMIT;
-                $this->body = $decoded;
-                return;
-            }
-
-            $chunk_length = strlen($matches[0]);
-            $decoded .= substr($encoded, $chunk_length, $length);
-            $encoded = substr($encoded, $chunk_length + $length + 2);
-
-            // BC for PHP < 8.0: substr() can return bool instead of string
-            $encoded = ($encoded === false) ? '' : $encoded;
-
-            if (trim($encoded) === '0' || empty($encoded)) {
-                $this->state = self::STATE_EMIT;
-                $this->body = $decoded;
-                return;
-            }
-        }
-    }
-
-    /**
-     * Prepare headers (take care of proxies headers)
-     *
-     * @param string  $headers Raw headers
-     * @param integer $count   Redirection count. Default to 1.
-     *
-     * @return string
-     */
-    public static function prepareHeaders($headers, $count = 1)
-    {
-        $data = explode("\r\n\r\n", $headers, $count);
-        $data = array_pop($data);
-        if (false !== stripos($data, "HTTP/1.0 200 Connection established\r\n")) {
-            $exploded = explode("\r\n\r\n", $data, 2);
-            $data = end($exploded);
-        }
-        if (false !== stripos($data, "HTTP/1.1 200 Connection established\r\n")) {
-            $exploded = explode("\r\n\r\n", $data, 2);
-            $data = end($exploded);
-        }
-        return $data;
-    }
-}
-
-class_alias('SimplePie\HTTP\Parser', 'SimplePie_HTTP_Parser');
-
-}
-
-namespace SimplePie {
-
-/**
- * IRI parser/serialiser/normaliser
- *
- * @package SimplePie
- * @subpackage HTTP
- * @author Sam Sneddon
- * @author Steve Minutillo
- * @author Ryan McCue
- * @copyright 2007-2012 Sam Sneddon, Steve Minutillo, Ryan McCue
- * @license http://www.opensource.org/licenses/bsd-license.php
- */
-class IRI
-{
-    /**
-     * Scheme
-     *
-     * @var string
-     */
-    protected $scheme = null;
-
-    /**
-     * User Information
-     *
-     * @var string
-     */
-    protected $iuserinfo = null;
-
-    /**
-     * ihost
-     *
-     * @var string
-     */
-    protected $ihost = null;
-
-    /**
-     * Port
-     *
-     * @var string
-     */
-    protected $port = null;
-
-    /**
-     * ipath
-     *
-     * @var string
-     */
-    protected $ipath = '';
-
-    /**
-     * iquery
-     *
-     * @var string
-     */
-    protected $iquery = null;
-
-    /**
-     * ifragment
-     *
-     * @var string
-     */
-    protected $ifragment = null;
-
-    /**
-     * Normalization database
-     *
-     * Each key is the scheme, each value is an array with each key as the IRI
-     * part and value as the default value for that part.
-     */
-    protected $normalization = [
-        'acap' => [
-            'port' => 674
-        ],
-        'dict' => [
-            'port' => 2628
-        ],
-        'file' => [
-            'ihost' => 'localhost'
-        ],
-        'http' => [
-            'port' => 80,
-            'ipath' => '/'
-        ],
-        'https' => [
-            'port' => 443,
-            'ipath' => '/'
-        ],
-    ];
-
-    /**
-     * Return the entire IRI when you try and read the object as a string
-     *
-     * @return string
-     */
-    public function __toString()
-    {
-        return $this->get_iri();
-    }
-
-    /**
-     * Overload __set() to provide access via properties
-     *
-     * @param string $name Property name
-     * @param mixed $value Property value
-     */
-    public function __set($name, $value)
-    {
-        if (method_exists($this, 'set_' . $name)) {
-            call_user_func([$this, 'set_' . $name], $value);
-        } elseif (
-            $name === 'iauthority'
-            || $name === 'iuserinfo'
-            || $name === 'ihost'
-            || $name === 'ipath'
-            || $name === 'iquery'
-            || $name === 'ifragment'
-        ) {
-            call_user_func([$this, 'set_' . substr($name, 1)], $value);
-        }
-    }
-
-    /**
-     * Overload __get() to provide access via properties
-     *
-     * @param string $name Property name
-     * @return mixed
-     */
-    public function __get($name)
-    {
-        // isset() returns false for null, we don't want to do that
-        // Also why we use array_key_exists below instead of isset()
-        $props = get_object_vars($this);
-
-        if (
-            $name === 'iri' ||
-            $name === 'uri' ||
-            $name === 'iauthority' ||
-            $name === 'authority'
-        ) {
-            $return = $this->{"get_$name"}();
-        } elseif (array_key_exists($name, $props)) {
-            $return = $this->$name;
-        }
-        // host -> ihost
-        elseif (($prop = 'i' . $name) && array_key_exists($prop, $props)) {
-            $name = $prop;
-            $return = $this->$prop;
-        }
-        // ischeme -> scheme
-        elseif (($prop = substr($name, 1)) && array_key_exists($prop, $props)) {
-            $name = $prop;
-            $return = $this->$prop;
-        } else {
-            trigger_error('Undefined property: ' . get_class($this) . '::' . $name, E_USER_NOTICE);
-            $return = null;
-        }
-
-        if ($return === null && isset($this->normalization[$this->scheme][$name])) {
-            return $this->normalization[$this->scheme][$name];
-        }
-
-        return $return;
-    }
-
-    /**
-     * Overload __isset() to provide access via properties
-     *
-     * @param string $name Property name
-     * @return bool
-     */
-    public function __isset($name)
-    {
-        return method_exists($this, 'get_' . $name) || isset($this->$name);
-    }
-
-    /**
-     * Overload __unset() to provide access via properties
-     *
-     * @param string $name Property name
-     */
-    public function __unset($name)
-    {
-        if (method_exists($this, 'set_' . $name)) {
-            call_user_func([$this, 'set_' . $name], '');
-        }
-    }
-
-    /**
-     * Create a new IRI object, from a specified string
-     *
-     * @param string $iri
-     */
-    public function __construct($iri = null)
-    {
-        $this->set_iri($iri);
-    }
-
-    /**
-     * Clean up
-     */
-    public function __destruct()
-    {
-        $this->set_iri(null, true);
-        $this->set_path(null, true);
-        $this->set_authority(null, true);
-    }
-
-    /**
-     * Create a new IRI object by resolving a relative IRI
-     *
-     * Returns false if $base is not absolute, otherwise an IRI.
-     *
-     * @param IRI|string $base (Absolute) Base IRI
-     * @param IRI|string $relative Relative IRI
-     * @return IRI|false
-     */
-    public static function absolutize($base, $relative)
-    {
-        if (!($relative instanceof IRI)) {
-            $relative = new IRI($relative);
-        }
-        if (!$relative->is_valid()) {
-            return false;
-        } elseif ($relative->scheme !== null) {
-            return clone $relative;
-        } else {
-            if (!($base instanceof IRI)) {
-                $base = new IRI($base);
-            }
-            if ($base->scheme !== null && $base->is_valid()) {
-                if ($relative->get_iri() !== '') {
-                    if ($relative->iuserinfo !== null || $relative->ihost !== null || $relative->port !== null) {
-                        $target = clone $relative;
-                        $target->scheme = $base->scheme;
-                    } else {
-                        $target = new IRI();
-                        $target->scheme = $base->scheme;
-                        $target->iuserinfo = $base->iuserinfo;
-                        $target->ihost = $base->ihost;
-                        $target->port = $base->port;
-                        if ($relative->ipath !== '') {
-                            if ($relative->ipath[0] === '/') {
-                                $target->ipath = $relative->ipath;
-                            } elseif (($base->iuserinfo !== null || $base->ihost !== null || $base->port !== null) && $base->ipath === '') {
-                                $target->ipath = '/' . $relative->ipath;
-                            } elseif (($last_segment = strrpos($base->ipath, '/')) !== false) {
-                                $target->ipath = substr($base->ipath, 0, $last_segment + 1) . $relative->ipath;
-                            } else {
-                                $target->ipath = $relative->ipath;
-                            }
-                            $target->ipath = $target->remove_dot_segments($target->ipath);
-                            $target->iquery = $relative->iquery;
-                        } else {
-                            $target->ipath = $base->ipath;
-                            if ($relative->iquery !== null) {
-                                $target->iquery = $relative->iquery;
-                            } elseif ($base->iquery !== null) {
-                                $target->iquery = $base->iquery;
-                            }
-                        }
-                        $target->ifragment = $relative->ifragment;
-                    }
-                } else {
-                    $target = clone $base;
-                    $target->ifragment = null;
-                }
-                $target->scheme_normalization();
-                return $target;
-            }
-
-            return false;
-        }
-    }
-
-    /**
-     * Parse an IRI into scheme/authority/path/query/fragment segments
-     *
-     * @param string $iri
-     * @return array
-     */
-    protected function parse_iri($iri)
-    {
-        $iri = trim($iri, "\x20\x09\x0A\x0C\x0D");
-        if (preg_match('/^((?P<scheme>[^:\/?#]+):)?(\/\/(?P<authority>[^\/?#]*))?(?P<path>[^?#]*)(\?(?P<query>[^#]*))?(#(?P<fragment>.*))?$/', $iri, $match)) {
-            if ($match[1] === '') {
-                $match['scheme'] = null;
-            }
-            if (!isset($match[3]) || $match[3] === '') {
-                $match['authority'] = null;
-            }
-            if (!isset($match[5])) {
-                $match['path'] = '';
-            }
-            if (!isset($match[6]) || $match[6] === '') {
-                $match['query'] = null;
-            }
-            if (!isset($match[8]) || $match[8] === '') {
-                $match['fragment'] = null;
-            }
-            return $match;
-        }
-
-        // This can occur when a paragraph is accidentally parsed as a URI
-        return false;
-    }
-
-    /**
-     * Remove dot segments from a path
-     *
-     * @param string $input
-     * @return string
-     */
-    protected function remove_dot_segments($input)
-    {
-        $output = '';
-        while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..') {
-            // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
-            if (strpos($input, '../') === 0) {
-                $input = substr($input, 3);
-            } elseif (strpos($input, './') === 0) {
-                $input = substr($input, 2);
-            }
-            // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
-            elseif (strpos($input, '/./') === 0) {
-                $input = substr($input, 2);
-            } elseif ($input === '/.') {
-                $input = '/';
-            }
-            // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
-            elseif (strpos($input, '/../') === 0) {
-                $input = substr($input, 3);
-                $output = substr_replace($output, '', intval(strrpos($output, '/')));
-            } elseif ($input === '/..') {
-                $input = '/';
-                $output = substr_replace($output, '', intval(strrpos($output, '/')));
-            }
-            // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
-            elseif ($input === '.' || $input === '..') {
-                $input = '';
-            }
-            // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
-            elseif (($pos = strpos($input, '/', 1)) !== false) {
-                $output .= substr($input, 0, $pos);
-                $input = substr_replace($input, '', 0, $pos);
-            } else {
-                $output .= $input;
-                $input = '';
-            }
-        }
-        return $output . $input;
-    }
-
-    /**
-     * Replace invalid character with percent encoding
-     *
-     * @param string $string Input string
-     * @param string $extra_chars Valid characters not in iunreserved or
-     *                            iprivate (this is ASCII-only)
-     * @param bool $iprivate Allow iprivate
-     * @return string
-     */
-    protected function replace_invalid_with_pct_encoding($string, $extra_chars, $iprivate = false)
-    {
-        // Normalize as many pct-encoded sections as possible
-        $string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', [$this, 'remove_iunreserved_percent_encoded'], $string);
-
-        // Replace invalid percent characters
-        $string = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $string);
-
-        // Add unreserved and % to $extra_chars (the latter is safe because all
-        // pct-encoded sections are now valid).
-        $extra_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';
-
-        // Now replace any bytes that aren't allowed with their pct-encoded versions
-        $position = 0;
-        $strlen = strlen($string);
-        while (($position += strspn($string, $extra_chars, $position)) < $strlen) {
-            $value = ord($string[$position]);
-            $character = 0;
-
-            // Start position
-            $start = $position;
-
-            // By default we are valid
-            $valid = true;
-
-            // No one byte sequences are valid due to the while.
-            // Two byte sequence:
-            if (($value & 0xE0) === 0xC0) {
-                $character = ($value & 0x1F) << 6;
-                $length = 2;
-                $remaining = 1;
-            }
-            // Three byte sequence:
-            elseif (($value & 0xF0) === 0xE0) {
-                $character = ($value & 0x0F) << 12;
-                $length = 3;
-                $remaining = 2;
-            }
-            // Four byte sequence:
-            elseif (($value & 0xF8) === 0xF0) {
-                $character = ($value & 0x07) << 18;
-                $length = 4;
-                $remaining = 3;
-            }
-            // Invalid byte:
-            else {
-                $valid = false;
-                $length = 1;
-                $remaining = 0;
-            }
-
-            if ($remaining) {
-                if ($position + $length <= $strlen) {
-                    for ($position++; $remaining; $position++) {
-                        $value = ord($string[$position]);
-
-                        // Check that the byte is valid, then add it to the character:
-                        if (($value & 0xC0) === 0x80) {
-                            $character |= ($value & 0x3F) << (--$remaining * 6);
-                        }
-                        // If it is invalid, count the sequence as invalid and reprocess the current byte:
-                        else {
-                            $valid = false;
-                            $position--;
-                            break;
-                        }
-                    }
-                } else {
-                    $position = $strlen - 1;
-                    $valid = false;
-                }
-            }
-
-            // Percent encode anything invalid or not in ucschar
-            if (
-                // Invalid sequences
-                !$valid
-                // Non-shortest form sequences are invalid
-                || $length > 1 && $character <= 0x7F
-                || $length > 2 && $character <= 0x7FF
-                || $length > 3 && $character <= 0xFFFF
-                // Outside of range of ucschar codepoints
-                // Noncharacters
-                || ($character & 0xFFFE) === 0xFFFE
-                || $character >= 0xFDD0 && $character <= 0xFDEF
-                || (
-                    // Everything else not in ucschar
-                    $character > 0xD7FF && $character < 0xF900
-                    || $character < 0xA0
-                    || $character > 0xEFFFD
-                )
-                && (
-                    // Everything not in iprivate, if it applies
-                    !$iprivate
-                    || $character < 0xE000
-                    || $character > 0x10FFFD
-                )
-            ) {
-                // If we were a character, pretend we weren't, but rather an error.
-                if ($valid) {
-                    $position--;
-                }
-
-                for ($j = $start; $j <= $position; $j++) {
-                    $string = substr_replace($string, sprintf('%%%02X', ord($string[$j])), $j, 1);
-                    $j += 2;
-                    $position += 2;
-                    $strlen += 2;
-                }
-            }
-        }
-
-        return $string;
-    }
-
-    /**
-     * Callback function for preg_replace_callback.
-     *
-     * Removes sequences of percent encoded bytes that represent UTF-8
-     * encoded characters in iunreserved
-     *
-     * @param array $match PCRE match
-     * @return string Replacement
-     */
-    protected function remove_iunreserved_percent_encoded($match)
-    {
-        // As we just have valid percent encoded sequences we can just explode
-        // and ignore the first member of the returned array (an empty string).
-        $bytes = explode('%', $match[0]);
-
-        // Initialize the new string (this is what will be returned) and that
-        // there are no bytes remaining in the current sequence (unsurprising
-        // at the first byte!).
-        $string = '';
-        $remaining = 0;
-
-        // these variables will be initialized in the loop but PHPStan is not able to detect it currently
-        $start = 0;
-        $character = 0;
-        $length = 0;
-        $valid = true;
-
-        // Loop over each and every byte, and set $value to its value
-        for ($i = 1, $len = count($bytes); $i < $len; $i++) {
-            $value = hexdec($bytes[$i]);
-
-            // If we're the first byte of sequence:
-            if (!$remaining) {
-                // Start position
-                $start = $i;
-
-                // By default we are valid
-                $valid = true;
-
-                // One byte sequence:
-                if ($value <= 0x7F) {
-                    $character = $value;
-                    $length = 1;
-                }
-                // Two byte sequence:
-                elseif (($value & 0xE0) === 0xC0) {
-                    $character = ($value & 0x1F) << 6;
-                    $length = 2;
-                    $remaining = 1;
-                }
-                // Three byte sequence:
-                elseif (($value & 0xF0) === 0xE0) {
-                    $character = ($value & 0x0F) << 12;
-                    $length = 3;
-                    $remaining = 2;
-                }
-                // Four byte sequence:
-                elseif (($value & 0xF8) === 0xF0) {
-                    $character = ($value & 0x07) << 18;
-                    $length = 4;
-                    $remaining = 3;
-                }
-                // Invalid byte:
-                else {
-                    $valid = false;
-                    $remaining = 0;
-                }
-            }
-            // Continuation byte:
-            else {
-                // Check that the byte is valid, then add it to the character:
-                if (($value & 0xC0) === 0x80) {
-                    $remaining--;
-                    $character |= ($value & 0x3F) << ($remaining * 6);
-                }
-                // If it is invalid, count the sequence as invalid and reprocess the current byte as the start of a sequence:
-                else {
-                    $valid = false;
-                    $remaining = 0;
-                    $i--;
-                }
-            }
-
-            // If we've reached the end of the current byte sequence, append it to Unicode::$data
-            if (!$remaining) {
-                // Percent encode anything invalid or not in iunreserved
-                if (
-                    // Invalid sequences
-                    !$valid
-                    // Non-shortest form sequences are invalid
-                    || $length > 1 && $character <= 0x7F
-                    || $length > 2 && $character <= 0x7FF
-                    || $length > 3 && $character <= 0xFFFF
-                    // Outside of range of iunreserved codepoints
-                    || $character < 0x2D
-                    || $character > 0xEFFFD
-                    // Noncharacters
-                    || ($character & 0xFFFE) === 0xFFFE
-                    || $character >= 0xFDD0 && $character <= 0xFDEF
-                    // Everything else not in iunreserved (this is all BMP)
-                    || $character === 0x2F
-                    || $character > 0x39 && $character < 0x41
-                    || $character > 0x5A && $character < 0x61
-                    || $character > 0x7A && $character < 0x7E
-                    || $character > 0x7E && $character < 0xA0
-                    || $character > 0xD7FF && $character < 0xF900
-                ) {
-                    for ($j = $start; $j <= $i; $j++) {
-                        $string .= '%' . strtoupper($bytes[$j]);
-                    }
-                } else {
-                    for ($j = $start; $j <= $i; $j++) {
-                        $string .= chr(hexdec($bytes[$j]));
-                    }
-                }
-            }
-        }
-
-        // If we have any bytes left over they are invalid (i.e., we are
-        // mid-way through a multi-byte sequence)
-        if ($remaining) {
-            for ($j = $start; $j < $len; $j++) {
-                $string .= '%' . strtoupper($bytes[$j]);
-            }
-        }
-
-        return $string;
-    }
-
-    protected function scheme_normalization()
-    {
-        if (isset($this->normalization[$this->scheme]['iuserinfo']) && $this->iuserinfo === $this->normalization[$this->scheme]['iuserinfo']) {
-            $this->iuserinfo = null;
-        }
-        if (isset($this->normalization[$this->scheme]['ihost']) && $this->ihost === $this->normalization[$this->scheme]['ihost']) {
-            $this->ihost = null;
-        }
-        if (isset($this->normalization[$this->scheme]['port']) && $this->port === $this->normalization[$this->scheme]['port']) {
-            $this->port = null;
-        }
-        if (isset($this->normalization[$this->scheme]['ipath']) && $this->ipath === $this->normalization[$this->scheme]['ipath']) {
-            $this->ipath = '';
-        }
-        if (isset($this->normalization[$this->scheme]['iquery']) && $this->iquery === $this->normalization[$this->scheme]['iquery']) {
-            $this->iquery = null;
-        }
-        if (isset($this->normalization[$this->scheme]['ifragment']) && $this->ifragment === $this->normalization[$this->scheme]['ifragment']) {
-            $this->ifragment = null;
-        }
-    }
-
-    /**
-     * Check if the object represents a valid IRI. This needs to be done on each
-     * call as some things change depending on another part of the IRI.
-     *
-     * @return bool
-     */
-    public function is_valid()
-    {
-        if ($this->ipath === '') {
-            return true;
-        }
-
-        $isauthority = $this->iuserinfo !== null || $this->ihost !== null ||
-            $this->port !== null;
-        if ($isauthority && $this->ipath[0] === '/') {
-            return true;
-        }
-
-        if (!$isauthority && (substr($this->ipath, 0, 2) === '//')) {
-            return false;
-        }
-
-        // Relative urls cannot have a colon in the first path segment (and the
-        // slashes themselves are not included so skip the first character).
-        if (!$this->scheme && !$isauthority &&
-            strpos($this->ipath, ':') !== false &&
-            strpos($this->ipath, '/', 1) !== false &&
-            strpos($this->ipath, ':') < strpos($this->ipath, '/', 1)) {
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Set the entire IRI. Returns true on success, false on failure (if there
-     * are any invalid characters).
-     *
-     * @param string $iri
-     * @return bool
-     */
-    public function set_iri($iri, $clear_cache = false)
-    {
-        static $cache;
-        if ($clear_cache) {
-            $cache = null;
-            return;
-        }
-        if (!$cache) {
-            $cache = [];
-        }
-
-        if ($iri === null) {
-            return true;
-        } elseif (isset($cache[$iri])) {
-            [
-                $this->scheme,
-                $this->iuserinfo,
-                $this->ihost,
-                $this->port,
-                $this->ipath,
-                $this->iquery,
-                $this->ifragment,
-                $return
-            ] = $cache[$iri];
-
-            return $return;
-        }
-
-        $parsed = $this->parse_iri((string) $iri);
-        if (!$parsed) {
-            return false;
-        }
-
-        $return = $this->set_scheme($parsed['scheme'])
-            && $this->set_authority($parsed['authority'])
-            && $this->set_path($parsed['path'])
-            && $this->set_query($parsed['query'])
-            && $this->set_fragment($parsed['fragment']);
-
-        $cache[$iri] = [
-            $this->scheme,
-            $this->iuserinfo,
-            $this->ihost,
-            $this->port,
-            $this->ipath,
-            $this->iquery,
-            $this->ifragment,
-            $return
-        ];
-
-        return $return;
-    }
-
-    /**
-     * Set the scheme. Returns true on success, false on failure (if there are
-     * any invalid characters).
-     *
-     * @param string $scheme
-     * @return bool
-     */
-    public function set_scheme($scheme)
-    {
-        if ($scheme === null) {
-            $this->scheme = null;
-        } elseif (!preg_match('/^[A-Za-z][0-9A-Za-z+\-.]*$/', $scheme)) {
-            $this->scheme = null;
-            return false;
-        } else {
-            $this->scheme = strtolower($scheme);
-        }
-        return true;
-    }
-
-    /**
-     * Set the authority. Returns true on success, false on failure (if there are
-     * any invalid characters).
-     *
-     * @param string $authority
-     * @return bool
-     */
-    public function set_authority($authority, $clear_cache = false)
-    {
-        static $cache;
-        if ($clear_cache) {
-            $cache = null;
-            return;
-        }
-        if (!$cache) {
-            $cache = [];
-        }
-
-        if ($authority === null) {
-            $this->iuserinfo = null;
-            $this->ihost = null;
-            $this->port = null;
-            return true;
-        } elseif (isset($cache[$authority])) {
-            [
-                $this->iuserinfo,
-                $this->ihost,
-                $this->port,
-                $return
-            ] = $cache[$authority];
-
-            return $return;
-        }
-
-        $remaining = $authority;
-        if (($iuserinfo_end = strrpos($remaining, '@')) !== false) {
-            $iuserinfo = substr($remaining, 0, $iuserinfo_end);
-            $remaining = substr($remaining, $iuserinfo_end + 1);
-        } else {
-            $iuserinfo = null;
-        }
-        if (($port_start = strpos($remaining, ':', intval(strpos($remaining, ']')))) !== false) {
-            if (($port = substr($remaining, $port_start + 1)) === false) {
-                $port = null;
-            }
-            $remaining = substr($remaining, 0, $port_start);
-        } else {
-            $port = null;
-        }
-
-        $return = $this->set_userinfo($iuserinfo) &&
-                  $this->set_host($remaining) &&
-                  $this->set_port($port);
-
-        $cache[$authority] = [
-            $this->iuserinfo,
-            $this->ihost,
-            $this->port,
-            $return
-        ];
-
-        return $return;
-    }
-
-    /**
-     * Set the iuserinfo.
-     *
-     * @param string $iuserinfo
-     * @return bool
-     */
-    public function set_userinfo($iuserinfo)
-    {
-        if ($iuserinfo === null) {
-            $this->iuserinfo = null;
-        } else {
-            $this->iuserinfo = $this->replace_invalid_with_pct_encoding($iuserinfo, '!$&\'()*+,;=:');
-            $this->scheme_normalization();
-        }
-
-        return true;
-    }
-
-    /**
-     * Set the ihost. Returns true on success, false on failure (if there are
-     * any invalid characters).
-     *
-     * @param string $ihost
-     * @return bool
-     */
-    public function set_host($ihost)
-    {
-        if ($ihost === null) {
-            $this->ihost = null;
-            return true;
-        } elseif (substr($ihost, 0, 1) === '[' && substr($ihost, -1) === ']') {
-            if (\SimplePie\Net\IPv6::check_ipv6(substr($ihost, 1, -1))) {
-                $this->ihost = '[' . \SimplePie\Net\IPv6::compress(substr($ihost, 1, -1)) . ']';
-            } else {
-                $this->ihost = null;
-                return false;
-            }
-        } else {
-            $ihost = $this->replace_invalid_with_pct_encoding($ihost, '!$&\'()*+,;=');
-
-            // Lowercase, but ignore pct-encoded sections (as they should
-            // remain uppercase). This must be done after the previous step
-            // as that can add unescaped characters.
-            $position = 0;
-            $strlen = strlen($ihost);
-            while (($position += strcspn($ihost, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ%', $position)) < $strlen) {
-                if ($ihost[$position] === '%') {
-                    $position += 3;
-                } else {
-                    $ihost[$position] = strtolower($ihost[$position]);
-                    $position++;
-                }
-            }
-
-            $this->ihost = $ihost;
-        }
-
-        $this->scheme_normalization();
-
-        return true;
-    }
-
-    /**
-     * Set the port. Returns true on success, false on failure (if there are
-     * any invalid characters).
-     *
-     * @param string $port
-     * @return bool
-     */
-    public function set_port($port)
-    {
-        if ($port === null) {
-            $this->port = null;
-            return true;
-        } elseif (strspn($port, '0123456789') === strlen($port)) {
-            $this->port = (int) $port;
-            $this->scheme_normalization();
-            return true;
-        }
-
-        $this->port = null;
-        return false;
-    }
-
-    /**
-     * Set the ipath.
-     *
-     * @param string $ipath
-     * @return bool
-     */
-    public function set_path($ipath, $clear_cache = false)
-    {
-        static $cache;
-        if ($clear_cache) {
-            $cache = null;
-            return;
-        }
-        if (!$cache) {
-            $cache = [];
-        }
-
-        $ipath = (string) $ipath;
-
-        if (isset($cache[$ipath])) {
-            $this->ipath = $cache[$ipath][(int) ($this->scheme !== null)];
-        } else {
-            $valid = $this->replace_invalid_with_pct_encoding($ipath, '!$&\'()*+,;=@:/');
-            $removed = $this->remove_dot_segments($valid);
-
-            $cache[$ipath] = [$valid, $removed];
-            $this->ipath =  ($this->scheme !== null) ? $removed : $valid;
-        }
-
-        $this->scheme_normalization();
-        return true;
-    }
-
-    /**
-     * Set the iquery.
-     *
-     * @param string $iquery
-     * @return bool
-     */
-    public function set_query($iquery)
-    {
-        if ($iquery === null) {
-            $this->iquery = null;
-        } else {
-            $this->iquery = $this->replace_invalid_with_pct_encoding($iquery, '!$&\'()*+,;=:@/?', true);
-            $this->scheme_normalization();
-        }
-        return true;
-    }
-
-    /**
-     * Set the ifragment.
-     *
-     * @param string $ifragment
-     * @return bool
-     */
-    public function set_fragment($ifragment)
-    {
-        if ($ifragment === null) {
-            $this->ifragment = null;
-        } else {
-            $this->ifragment = $this->replace_invalid_with_pct_encoding($ifragment, '!$&\'()*+,;=:@/?');
-            $this->scheme_normalization();
-        }
-        return true;
-    }
-
-    /**
-     * Convert an IRI to a URI (or parts thereof)
-     *
-     * @return string
-     */
-    public function to_uri($string)
-    {
-        static $non_ascii;
-        if (!$non_ascii) {
-            $non_ascii = implode('', range("\x80", "\xFF"));
-        }
-
-        $position = 0;
-        $strlen = strlen($string);
-        while (($position += strcspn($string, $non_ascii, $position)) < $strlen) {
-            $string = substr_replace($string, sprintf('%%%02X', ord($string[$position])), $position, 1);
-            $position += 3;
-            $strlen += 2;
-        }
-
-        return $string;
-    }
-
-    /**
-     * Get the complete IRI
-     *
-     * @return string
-     */
-    public function get_iri()
-    {
-        if (!$this->is_valid()) {
-            return false;
-        }
-
-        $iri = '';
-        if ($this->scheme !== null) {
-            $iri .= $this->scheme . ':';
-        }
-        if (($iauthority = $this->get_iauthority()) !== null) {
-            $iri .= '//' . $iauthority;
-        }
-        if ($this->ipath !== '') {
-            $iri .= $this->ipath;
-        } elseif (!empty($this->normalization[$this->scheme]['ipath']) && $iauthority !== null && $iauthority !== '') {
-            $iri .= $this->normalization[$this->scheme]['ipath'];
-        }
-        if ($this->iquery !== null) {
-            $iri .= '?' . $this->iquery;
-        }
-        if ($this->ifragment !== null) {
-            $iri .= '#' . $this->ifragment;
-        }
-
-        return $iri;
-    }
-
-    /**
-     * Get the complete URI
-     *
-     * @return string
-     */
-    public function get_uri()
-    {
-        return $this->to_uri($this->get_iri());
-    }
-
-    /**
-     * Get the complete iauthority
-     *
-     * @return string
-     */
-    protected function get_iauthority()
-    {
-        if ($this->iuserinfo !== null || $this->ihost !== null || $this->port !== null) {
-            $iauthority = '';
-            if ($this->iuserinfo !== null) {
-                $iauthority .= $this->iuserinfo . '@';
-            }
-            if ($this->ihost !== null) {
-                $iauthority .= $this->ihost;
-            }
-            if ($this->port !== null && $this->port !== 0) {
-                $iauthority .= ':' . $this->port;
-            }
-            return $iauthority;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the complete authority
-     *
-     * @return string
-     */
-    protected function get_authority()
-    {
-        $iauthority = $this->get_iauthority();
-        if (is_string($iauthority)) {
-            return $this->to_uri($iauthority);
-        }
-
-        return $iauthority;
-    }
-}
-
-class_alias('SimplePie\IRI', 'SimplePie_IRI');
-
-}
-
-namespace SimplePie {
-
-/**
- * Manages all item-related data
- *
- * Used by {@see \SimplePie\SimplePie::get_item()} and {@see \SimplePie\SimplePie::get_items()}
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_item_class()}
- *
- * @package \SimplePie\SimplePie
- * @subpackage API
- */
-class Item implements RegistryAware
-{
-    /**
-     * Parent feed
-     *
-     * @access private
-     * @var \SimplePie\SimplePie
-     */
-    public $feed;
-
-    /**
-     * Raw data
-     *
-     * @access private
-     * @var array
-     */
-    public $data = [];
-
-    /**
-     * Registry object
-     *
-     * @see set_registry
-     * @var \SimplePie\Registry
-     */
-    protected $registry;
-
-    /**
-     * Create a new item object
-     *
-     * This is usually used by {@see \SimplePie\SimplePie::get_items} and
-     * {@see \SimplePie\SimplePie::get_item}. Avoid creating this manually.
-     *
-     * @param \SimplePie\SimplePie $feed Parent feed
-     * @param array $data Raw data
-     */
-    public function __construct($feed, $data)
-    {
-        $this->feed = $feed;
-        $this->data = $data;
-    }
-
-    /**
-     * Set the registry handler
-     *
-     * This is usually used by {@see \SimplePie\Registry::create}
-     *
-     * @since 1.3
-     * @param \SimplePie\Registry $registry
-     */
-    public function set_registry(\SimplePie\Registry $registry)/* : void */
-    {
-        $this->registry = $registry;
-    }
-
-    /**
-     * Get a string representation of the item
-     *
-     * @return string
-     */
-    public function __toString()
-    {
-        return md5(serialize($this->data));
-    }
-
-    /**
-     * Remove items that link back to this before destroying this object
-     */
-    public function __destruct()
-    {
-        if (!gc_enabled()) {
-            unset($this->feed);
-        }
-    }
-
-    /**
-     * Get data for an item-level element
-     *
-     * This method allows you to get access to ANY element/attribute that is a
-     * sub-element of the item/entry tag.
-     *
-     * See {@see \SimplePie\SimplePie::get_feed_tags()} for a description of the return value
-     *
-     * @since 1.0
-     * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
-     * @param string $namespace The URL of the XML namespace of the elements you're trying to access
-     * @param string $tag Tag name
-     * @return array
-     */
-    public function get_item_tags($namespace, $tag)
-    {
-        if (isset($this->data['child'][$namespace][$tag])) {
-            return $this->data['child'][$namespace][$tag];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the base URL value.
-     * Uses `<xml:base>`, or item link, or feed base URL.
-     *
-     * @param array $element
-     * @return string
-     */
-    public function get_base($element = [])
-    {
-        if (!empty($element['xml_base_explicit']) && isset($element['xml_base'])) {
-            return $element['xml_base'];
-        }
-        $link = $this->get_permalink();
-        if ($link != null) {
-            return $link;
-        }
-        return $this->feed->get_base($element);
-    }
-
-    /**
-     * Sanitize feed data
-     *
-     * @access private
-     * @see \SimplePie\SimplePie::sanitize()
-     * @param string $data Data to sanitize
-     * @param int $type One of the \SimplePie\SimplePie::CONSTRUCT_* constants
-     * @param string $base Base URL to resolve URLs against
-     * @return string Sanitized data
-     */
-    public function sanitize($data, $type, $base = '')
-    {
-        return $this->feed->sanitize($data, $type, $base);
-    }
-
-    /**
-     * Get the parent feed
-     *
-     * Note: this may not work as you think for multifeeds!
-     *
-     * @link http://simplepie.org/faq/typical_multifeed_gotchas#missing_data_from_feed
-     * @since 1.0
-     * @return \SimplePie\SimplePie
-     */
-    public function get_feed()
-    {
-        return $this->feed;
-    }
-
-    /**
-     * Get the unique identifier for the item
-     *
-     * This is usually used when writing code to check for new items in a feed.
-     *
-     * Uses `<atom:id>`, `<guid>`, `<dc:identifier>` or the `about` attribute
-     * for RDF. If none of these are supplied (or `$hash` is true), creates an
-     * MD5 hash based on the permalink, title and content.
-     *
-     * @since Beta 2
-     * @param boolean $hash Should we force using a hash instead of the supplied ID?
-     * @param string|false $fn User-supplied function to generate an hash
-     * @return string|null
-     */
-    public function get_id($hash = false, $fn = 'md5')
-    {
-        if (!$hash) {
-            if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'id')) {
-                return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'id')) {
-                return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'guid')) {
-                return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'identifier')) {
-                return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'identifier')) {
-                return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            } elseif (isset($this->data['attribs'][\SimplePie\SimplePie::NAMESPACE_RDF]['about'])) {
-                return $this->sanitize($this->data['attribs'][\SimplePie\SimplePie::NAMESPACE_RDF]['about'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-        }
-        if ($fn === false) {
-            return null;
-        } elseif (!is_callable($fn)) {
-            trigger_error('User-supplied function $fn must be callable', E_USER_WARNING);
-            $fn = 'md5';
-        }
-        return call_user_func(
-            $fn,
-            $this->get_permalink().$this->get_title().$this->get_content()
-        );
-    }
-
-    /**
-     * Get the title of the item
-     *
-     * Uses `<atom:title>`, `<title>` or `<dc:title>`
-     *
-     * @since Beta 2 (previously called `get_item_title` since 0.8)
-     * @return string|null
-     */
-    public function get_title()
-    {
-        if (!isset($this->data['title'])) {
-            if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'title')) {
-                $this->data['title'] = $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_10_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'title')) {
-                $this->data['title'] = $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_03_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_10, 'title')) {
-                $this->data['title'] = $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_090, 'title')) {
-                $this->data['title'] = $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'title')) {
-                $this->data['title'] = $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'title')) {
-                $this->data['title'] = $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'title')) {
-                $this->data['title'] = $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            } else {
-                $this->data['title'] = null;
-            }
-        }
-        return $this->data['title'];
-    }
-
-    /**
-     * Get the content for the item
-     *
-     * Prefers summaries over full content , but will return full content if a
-     * summary does not exist.
-     *
-     * To prefer full content instead, use {@see get_content}
-     *
-     * Uses `<atom:summary>`, `<description>`, `<dc:description>` or
-     * `<itunes:subtitle>`
-     *
-     * @since 0.8
-     * @param boolean $description_only Should we avoid falling back to the content?
-     * @return string|null
-     */
-    public function get_description($description_only = false)
-    {
-        if (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'summary')) &&
-            ($return = $this->sanitize($tags[0]['data'], $this->registry->call(Misc::class, 'atom_10_construct_type', [$tags[0]['attribs']]), $this->get_base($tags[0])))) {
-            return $return;
-        } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'summary')) &&
-                ($return = $this->sanitize($tags[0]['data'], $this->registry->call(Misc::class, 'atom_03_construct_type', [$tags[0]['attribs']]), $this->get_base($tags[0])))) {
-            return $return;
-        } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_10, 'description')) &&
-                ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($tags[0])))) {
-            return $return;
-        } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'description')) &&
-                ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_HTML, $this->get_base($tags[0])))) {
-            return $return;
-        } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'description')) &&
-                ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT))) {
-            return $return;
-        } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'description')) &&
-                ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT))) {
-            return $return;
-        } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'summary')) &&
-                ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_HTML, $this->get_base($tags[0])))) {
-            return $return;
-        } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'subtitle')) &&
-                ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT))) {
-            return $return;
-        } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_090, 'description')) &&
-                ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_HTML))) {
-            return $return;
-        } elseif (!$description_only) {
-            return $this->get_content(true);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the content for the item
-     *
-     * Prefers full content over summaries, but will return a summary if full
-     * content does not exist.
-     *
-     * To prefer summaries instead, use {@see get_description}
-     *
-     * Uses `<atom:content>` or `<content:encoded>` (RSS 1.0 Content Module)
-     *
-     * @since 1.0
-     * @param boolean $content_only Should we avoid falling back to the description?
-     * @return string|null
-     */
-    public function get_content($content_only = false)
-    {
-        if (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'content')) &&
-            ($return = $this->sanitize($tags[0]['data'], $this->registry->call(Misc::class, 'atom_10_content_construct_type', [$tags[0]['attribs']]), $this->get_base($tags[0])))) {
-            return $return;
-        } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'content')) &&
-                ($return = $this->sanitize($tags[0]['data'], $this->registry->call(Misc::class, 'atom_03_construct_type', [$tags[0]['attribs']]), $this->get_base($tags[0])))) {
-            return $return;
-        } elseif (($tags = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded')) &&
-                ($return = $this->sanitize($tags[0]['data'], \SimplePie\SimplePie::CONSTRUCT_HTML, $this->get_base($tags[0])))) {
-            return $return;
-        } elseif (!$content_only) {
-            return $this->get_description(true);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the media:thumbnail of the item
-     *
-     * Uses `<media:thumbnail>`
-     *
-     *
-     * @return array|null
-     */
-    public function get_thumbnail()
-    {
-        if (!isset($this->data['thumbnail'])) {
-            if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'thumbnail')) {
-                $thumbnail = $return[0]['attribs'][''];
-                if (empty($thumbnail['url'])) {
-                    $this->data['thumbnail'] = null;
-                } else {
-                    $thumbnail['url'] = $this->sanitize($thumbnail['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($return[0]));
-                    $this->data['thumbnail'] = $thumbnail;
-                }
-            } else {
-                $this->data['thumbnail'] = null;
-            }
-        }
-        return $this->data['thumbnail'];
-    }
-
-    /**
-     * Get a category for the item
-     *
-     * @since Beta 3 (previously called `get_categories()` since Beta 2)
-     * @param int $key The category that you want to return.  Remember that arrays begin with 0, not 1
-     * @return \SimplePie\Category|null
-     */
-    public function get_category($key = 0)
-    {
-        $categories = $this->get_categories();
-        if (isset($categories[$key])) {
-            return $categories[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all categories for the item
-     *
-     * Uses `<atom:category>`, `<category>` or `<dc:subject>`
-     *
-     * @since Beta 3
-     * @return \SimplePie\Category[]|null List of {@see \SimplePie\Category} objects
-     */
-    public function get_categories()
-    {
-        $categories = [];
-
-        $type = 'category';
-        foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, $type) as $category) {
-            $term = null;
-            $scheme = null;
-            $label = null;
-            if (isset($category['attribs']['']['term'])) {
-                $term = $this->sanitize($category['attribs']['']['term'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if (isset($category['attribs']['']['scheme'])) {
-                $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if (isset($category['attribs']['']['label'])) {
-                $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            $categories[] = $this->registry->create(Category::class, [$term, $scheme, $label, $type]);
-        }
-        foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, $type) as $category) {
-            // This is really the label, but keep this as the term also for BC.
-            // Label will also work on retrieving because that falls back to term.
-            $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            if (isset($category['attribs']['']['domain'])) {
-                $scheme = $this->sanitize($category['attribs']['']['domain'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            } else {
-                $scheme = null;
-            }
-            $categories[] = $this->registry->create(Category::class, [$term, $scheme, null, $type]);
-        }
-
-        $type = 'subject';
-        foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, $type) as $category) {
-            $categories[] = $this->registry->create(Category::class, [$this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null, $type]);
-        }
-        foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, $type) as $category) {
-            $categories[] = $this->registry->create(Category::class, [$this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null, $type]);
-        }
-
-        if (!empty($categories)) {
-            return array_unique($categories);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get an author for the item
-     *
-     * @since Beta 2
-     * @param int $key The author that you want to return.  Remember that arrays begin with 0, not 1
-     * @return \SimplePie\Author|null
-     */
-    public function get_author($key = 0)
-    {
-        $authors = $this->get_authors();
-        if (isset($authors[$key])) {
-            return $authors[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a contributor for the item
-     *
-     * @since 1.1
-     * @param int $key The contrbutor that you want to return.  Remember that arrays begin with 0, not 1
-     * @return \SimplePie\Author|null
-     */
-    public function get_contributor($key = 0)
-    {
-        $contributors = $this->get_contributors();
-        if (isset($contributors[$key])) {
-            return $contributors[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all contributors for the item
-     *
-     * Uses `<atom:contributor>`
-     *
-     * @since 1.1
-     * @return \SimplePie\Author[]|null List of {@see \SimplePie\Author} objects
-     */
-    public function get_contributors()
-    {
-        $contributors = [];
-        foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'contributor') as $contributor) {
-            $name = null;
-            $uri = null;
-            $email = null;
-            if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['name'][0]['data'])) {
-                $name = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['name'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]['data'])) {
-                $uri = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]));
-            }
-            if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['email'][0]['data'])) {
-                $email = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['email'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if ($name !== null || $email !== null || $uri !== null) {
-                $contributors[] = $this->registry->create(Author::class, [$name, $uri, $email]);
-            }
-        }
-        foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'contributor') as $contributor) {
-            $name = null;
-            $url = null;
-            $email = null;
-            if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['name'][0]['data'])) {
-                $name = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['name'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]['data'])) {
-                $url = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]));
-            }
-            if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['email'][0]['data'])) {
-                $email = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['email'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if ($name !== null || $email !== null || $url !== null) {
-                $contributors[] = $this->registry->create(Author::class, [$name, $url, $email]);
-            }
-        }
-
-        if (!empty($contributors)) {
-            return array_unique($contributors);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all authors for the item
-     *
-     * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>`
-     *
-     * @since Beta 2
-     * @return \SimplePie\Author[]|null List of {@see \SimplePie\Author} objects
-     */
-    public function get_authors()
-    {
-        $authors = [];
-        foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'author') as $author) {
-            $name = null;
-            $uri = null;
-            $email = null;
-            if (isset($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['name'][0]['data'])) {
-                $name = $this->sanitize($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['name'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if (isset($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]['data'])) {
-                $uri = $this->sanitize($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]));
-            }
-            if (isset($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['email'][0]['data'])) {
-                $email = $this->sanitize($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['email'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if ($name !== null || $email !== null || $uri !== null) {
-                $authors[] = $this->registry->create(Author::class, [$name, $uri, $email]);
-            }
-        }
-        if ($author = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'author')) {
-            $name = null;
-            $url = null;
-            $email = null;
-            if (isset($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['name'][0]['data'])) {
-                $name = $this->sanitize($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['name'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if (isset($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]['data'])) {
-                $url = $this->sanitize($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]));
-            }
-            if (isset($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['email'][0]['data'])) {
-                $email = $this->sanitize($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['email'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if ($name !== null || $email !== null || $url !== null) {
-                $authors[] = $this->registry->create(Author::class, [$name, $url, $email]);
-            }
-        }
-        if ($author = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'author')) {
-            $authors[] = $this->registry->create(Author::class, [null, null, $this->sanitize($author[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT)]);
-        }
-        foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'creator') as $author) {
-            $authors[] = $this->registry->create(Author::class, [$this->sanitize($author['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null]);
-        }
-        foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'creator') as $author) {
-            $authors[] = $this->registry->create(Author::class, [$this->sanitize($author['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null]);
-        }
-        foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'author') as $author) {
-            $authors[] = $this->registry->create(Author::class, [$this->sanitize($author['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null]);
-        }
-
-        if (!empty($authors)) {
-            return array_unique($authors);
-        } elseif (($source = $this->get_source()) && ($authors = $source->get_authors())) {
-            return $authors;
-        } elseif ($authors = $this->feed->get_authors()) {
-            return $authors;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the copyright info for the item
-     *
-     * Uses `<atom:rights>` or `<dc:rights>`
-     *
-     * @since 1.1
-     * @return string
-     */
-    public function get_copyright()
-    {
-        if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'rights')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_10_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'rights')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'rights')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the posting date/time for the item
-     *
-     * Uses `<atom:published>`, `<atom:updated>`, `<atom:issued>`,
-     * `<atom:modified>`, `<pubDate>` or `<dc:date>`
-     *
-     * Note: obeys PHP's timezone setting. To get a UTC date/time, use
-     * {@see get_gmdate}
-     *
-     * @since Beta 2 (previously called `get_item_date` since 0.8)
-     *
-     * @param string $date_format Supports any PHP date format from {@see http://php.net/date} (empty for the raw data)
-     * @return int|string|null
-     */
-    public function get_date($date_format = 'j F Y, g:i a')
-    {
-        if (!isset($this->data['date'])) {
-            if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'published')) {
-                $this->data['date']['raw'] = $return[0]['data'];
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'pubDate')) {
-                $this->data['date']['raw'] = $return[0]['data'];
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'date')) {
-                $this->data['date']['raw'] = $return[0]['data'];
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'date')) {
-                $this->data['date']['raw'] = $return[0]['data'];
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'updated')) {
-                $this->data['date']['raw'] = $return[0]['data'];
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'issued')) {
-                $this->data['date']['raw'] = $return[0]['data'];
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'created')) {
-                $this->data['date']['raw'] = $return[0]['data'];
-            } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'modified')) {
-                $this->data['date']['raw'] = $return[0]['data'];
-            }
-
-            if (!empty($this->data['date']['raw'])) {
-                $parser = $this->registry->call(Parse\Date::class, 'get');
-                $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']) ?: null;
-            } else {
-                $this->data['date'] = null;
-            }
-        }
-        if ($this->data['date']) {
-            $date_format = (string) $date_format;
-            switch ($date_format) {
-                case '':
-                    return $this->sanitize($this->data['date']['raw'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-
-                case 'U':
-                    return $this->data['date']['parsed'];
-
-                default:
-                    return date($date_format, $this->data['date']['parsed']);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the update date/time for the item
-     *
-     * Uses `<atom:updated>`
-     *
-     * Note: obeys PHP's timezone setting. To get a UTC date/time, use
-     * {@see get_gmdate}
-     *
-     * @param string $date_format Supports any PHP date format from {@see http://php.net/date} (empty for the raw data)
-     * @return int|string|null
-     */
-    public function get_updated_date($date_format = 'j F Y, g:i a')
-    {
-        if (!isset($this->data['updated'])) {
-            if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'updated')) {
-                $this->data['updated']['raw'] = $return[0]['data'];
-            }
-
-            if (!empty($this->data['updated']['raw'])) {
-                $parser = $this->registry->call(Parse\Date::class, 'get');
-                $this->data['updated']['parsed'] = $parser->parse($this->data['updated']['raw']) ?: null;
-            } else {
-                $this->data['updated'] = null;
-            }
-        }
-        if ($this->data['updated']) {
-            $date_format = (string) $date_format;
-            switch ($date_format) {
-                case '':
-                    return $this->sanitize($this->data['updated']['raw'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-
-                case 'U':
-                    return $this->data['updated']['parsed'];
-
-                default:
-                    return date($date_format, $this->data['updated']['parsed']);
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the localized posting date/time for the item
-     *
-     * Returns the date formatted in the localized language. To display in
-     * languages other than the server's default, you need to change the locale
-     * with {@link http://php.net/setlocale setlocale()}. The available
-     * localizations depend on which ones are installed on your web server.
-     *
-     * @since 1.0
-     *
-     * @param string $date_format Supports any PHP date format from {@see http://php.net/strftime} (empty for the raw data)
-     * @return int|string|null
-     */
-    public function get_local_date($date_format = '%c')
-    {
-        if (!$date_format) {
-            return $this->sanitize($this->get_date(''), \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        } elseif (($date = $this->get_date('U')) !== null && $date !== false) {
-            return strftime($date_format, $date);
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the posting date/time for the item (UTC time)
-     *
-     * @see get_date
-     * @param string $date_format Supports any PHP date format from {@see http://php.net/date}
-     * @return int|string|null
-     */
-    public function get_gmdate($date_format = 'j F Y, g:i a')
-    {
-        $date = $this->get_date('U');
-        if ($date === null) {
-            return null;
-        }
-
-        return gmdate($date_format, $date);
-    }
-
-    /**
-     * Get the update date/time for the item (UTC time)
-     *
-     * @see get_updated_date
-     * @param string $date_format Supports any PHP date format from {@see http://php.net/date}
-     * @return int|string|null
-     */
-    public function get_updated_gmdate($date_format = 'j F Y, g:i a')
-    {
-        $date = $this->get_updated_date('U');
-        if ($date === null) {
-            return null;
-        }
-
-        return gmdate($date_format, $date);
-    }
-
-    /**
-     * Get the permalink for the item
-     *
-     * Returns the first link available with a relationship of "alternate".
-     * Identical to {@see get_link()} with key 0
-     *
-     * @see get_link
-     * @since 0.8
-     * @return string|null Permalink URL
-     */
-    public function get_permalink()
-    {
-        $link = $this->get_link();
-        $enclosure = $this->get_enclosure(0);
-        if ($link !== null) {
-            return $link;
-        } elseif ($enclosure !== null) {
-            return $enclosure->get_link();
-        }
-
-        return null;
-    }
-
-    /**
-     * Get a single link for the item
-     *
-     * @since Beta 3
-     * @param int $key The link that you want to return.  Remember that arrays begin with 0, not 1
-     * @param string $rel The relationship of the link to return
-     * @return string|null Link URL
-     */
-    public function get_link($key = 0, $rel = 'alternate')
-    {
-        $links = $this->get_links($rel);
-        if ($links && $links[$key] !== null) {
-            return $links[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all links for the item
-     *
-     * Uses `<atom:link>`, `<link>` or `<guid>`
-     *
-     * @since Beta 2
-     * @param string $rel The relationship of links to return
-     * @return array|null Links found for the item (strings)
-     */
-    public function get_links($rel = 'alternate')
-    {
-        if (!isset($this->data['links'])) {
-            $this->data['links'] = [];
-            foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'link') as $link) {
-                if (isset($link['attribs']['']['href'])) {
-                    $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
-                    $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($link));
-                }
-            }
-            foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'link') as $link) {
-                if (isset($link['attribs']['']['href'])) {
-                    $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
-                    $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($link));
-                }
-            }
-            if ($links = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_10, 'link')) {
-                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($links[0]));
-            }
-            if ($links = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_090, 'link')) {
-                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($links[0]));
-            }
-            if ($links = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'link')) {
-                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($links[0]));
-            }
-            if ($links = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'guid')) {
-                if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true') {
-                    $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($links[0]));
-                }
-            }
-
-            $keys = array_keys($this->data['links']);
-            foreach ($keys as $key) {
-                if ($this->registry->call(Misc::class, 'is_isegment_nz_nc', [$key])) {
-                    if (isset($this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key])) {
-                        $this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key]);
-                        $this->data['links'][$key] =& $this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key];
-                    } else {
-                        $this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
-                    }
-                } elseif (substr($key, 0, 41) === \SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY) {
-                    $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
-                }
-                $this->data['links'][$key] = array_unique($this->data['links'][$key]);
-            }
-        }
-        if (isset($this->data['links'][$rel])) {
-            return $this->data['links'][$rel];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get an enclosure from the item
-     *
-     * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
-     *
-     * @since Beta 2
-     * @todo Add ability to prefer one type of content over another (in a media group).
-     * @param int $key The enclosure that you want to return.  Remember that arrays begin with 0, not 1
-     * @return \SimplePie\Enclosure|null
-     */
-    public function get_enclosure($key = 0, $prefer = null)
-    {
-        $enclosures = $this->get_enclosures();
-        if (isset($enclosures[$key])) {
-            return $enclosures[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get all available enclosures (podcasts, etc.)
-     *
-     * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
-     *
-     * At this point, we're pretty much assuming that all enclosures for an item
-     * are the same content.  Anything else is too complicated to
-     * properly support.
-     *
-     * @since Beta 2
-     * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
-     * @todo If an element exists at a level, but its value is empty, we should fall back to the value from the parent (if it exists).
-     * @return \SimplePie\Enclosure[]|null List of \SimplePie\Enclosure items
-     */
-    public function get_enclosures()
-    {
-        if (!isset($this->data['enclosures'])) {
-            $this->data['enclosures'] = [];
-
-            // Elements
-            $captions_parent = null;
-            $categories_parent = null;
-            $copyrights_parent = null;
-            $credits_parent = null;
-            $description_parent = null;
-            $duration_parent = null;
-            $hashes_parent = null;
-            $keywords_parent = null;
-            $player_parent = null;
-            $ratings_parent = null;
-            $restrictions_parent = null;
-            $thumbnails_parent = null;
-            $title_parent = null;
-
-            // Let's do the channel and item-level ones first, and just re-use them if we need to.
-            $parent = $this->get_feed();
-
-            // CAPTIONS
-            if ($captions = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'text')) {
-                foreach ($captions as $caption) {
-                    $caption_type = null;
-                    $caption_lang = null;
-                    $caption_startTime = null;
-                    $caption_endTime = null;
-                    $caption_text = null;
-                    if (isset($caption['attribs']['']['type'])) {
-                        $caption_type = $this->sanitize($caption['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($caption['attribs']['']['lang'])) {
-                        $caption_lang = $this->sanitize($caption['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($caption['attribs']['']['start'])) {
-                        $caption_startTime = $this->sanitize($caption['attribs']['']['start'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($caption['attribs']['']['end'])) {
-                        $caption_endTime = $this->sanitize($caption['attribs']['']['end'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($caption['data'])) {
-                        $caption_text = $this->sanitize($caption['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    $captions_parent[] = $this->registry->create(Caption::class, [$caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text]);
-                }
-            } elseif ($captions = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'text')) {
-                foreach ($captions as $caption) {
-                    $caption_type = null;
-                    $caption_lang = null;
-                    $caption_startTime = null;
-                    $caption_endTime = null;
-                    $caption_text = null;
-                    if (isset($caption['attribs']['']['type'])) {
-                        $caption_type = $this->sanitize($caption['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($caption['attribs']['']['lang'])) {
-                        $caption_lang = $this->sanitize($caption['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($caption['attribs']['']['start'])) {
-                        $caption_startTime = $this->sanitize($caption['attribs']['']['start'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($caption['attribs']['']['end'])) {
-                        $caption_endTime = $this->sanitize($caption['attribs']['']['end'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($caption['data'])) {
-                        $caption_text = $this->sanitize($caption['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    $captions_parent[] = $this->registry->create(Caption::class, [$caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text]);
-                }
-            }
-            if (is_array($captions_parent)) {
-                $captions_parent = array_values(array_unique($captions_parent));
-            }
-
-            // CATEGORIES
-            foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'category') as $category) {
-                $term = null;
-                $scheme = null;
-                $label = null;
-                if (isset($category['data'])) {
-                    $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-                if (isset($category['attribs']['']['scheme'])) {
-                    $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                } else {
-                    $scheme = 'http://search.yahoo.com/mrss/category_schema';
-                }
-                if (isset($category['attribs']['']['label'])) {
-                    $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-                $categories_parent[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
-            }
-            foreach ((array) $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'category') as $category) {
-                $term = null;
-                $scheme = null;
-                $label = null;
-                if (isset($category['data'])) {
-                    $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-                if (isset($category['attribs']['']['scheme'])) {
-                    $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                } else {
-                    $scheme = 'http://search.yahoo.com/mrss/category_schema';
-                }
-                if (isset($category['attribs']['']['label'])) {
-                    $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-                $categories_parent[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
-            }
-            foreach ((array) $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'category') as $category) {
-                $term = null;
-                $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
-                $label = null;
-                if (isset($category['attribs']['']['text'])) {
-                    $label = $this->sanitize($category['attribs']['']['text'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-                $categories_parent[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
-
-                if (isset($category['child'][\SimplePie\SimplePie::NAMESPACE_ITUNES]['category'])) {
-                    foreach ((array) $category['child'][\SimplePie\SimplePie::NAMESPACE_ITUNES]['category'] as $subcategory) {
-                        if (isset($subcategory['attribs']['']['text'])) {
-                            $label = $this->sanitize($subcategory['attribs']['']['text'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        }
-                        $categories_parent[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
-                    }
-                }
-            }
-            if (is_array($categories_parent)) {
-                $categories_parent = array_values(array_unique($categories_parent));
-            }
-
-            // COPYRIGHT
-            if ($copyright = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'copyright')) {
-                $copyright_url = null;
-                $copyright_label = null;
-                if (isset($copyright[0]['attribs']['']['url'])) {
-                    $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-                if (isset($copyright[0]['data'])) {
-                    $copyright_label = $this->sanitize($copyright[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-                $copyrights_parent = $this->registry->create(Copyright::class, [$copyright_url, $copyright_label]);
-            } elseif ($copyright = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'copyright')) {
-                $copyright_url = null;
-                $copyright_label = null;
-                if (isset($copyright[0]['attribs']['']['url'])) {
-                    $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-                if (isset($copyright[0]['data'])) {
-                    $copyright_label = $this->sanitize($copyright[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-                $copyrights_parent = $this->registry->create(Copyright::class, [$copyright_url, $copyright_label]);
-            }
-
-            // CREDITS
-            if ($credits = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'credit')) {
-                foreach ($credits as $credit) {
-                    $credit_role = null;
-                    $credit_scheme = null;
-                    $credit_name = null;
-                    if (isset($credit['attribs']['']['role'])) {
-                        $credit_role = $this->sanitize($credit['attribs']['']['role'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($credit['attribs']['']['scheme'])) {
-                        $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    } else {
-                        $credit_scheme = 'urn:ebu';
-                    }
-                    if (isset($credit['data'])) {
-                        $credit_name = $this->sanitize($credit['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    $credits_parent[] = $this->registry->create(Credit::class, [$credit_role, $credit_scheme, $credit_name]);
-                }
-            } elseif ($credits = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'credit')) {
-                foreach ($credits as $credit) {
-                    $credit_role = null;
-                    $credit_scheme = null;
-                    $credit_name = null;
-                    if (isset($credit['attribs']['']['role'])) {
-                        $credit_role = $this->sanitize($credit['attribs']['']['role'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($credit['attribs']['']['scheme'])) {
-                        $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    } else {
-                        $credit_scheme = 'urn:ebu';
-                    }
-                    if (isset($credit['data'])) {
-                        $credit_name = $this->sanitize($credit['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    $credits_parent[] = $this->registry->create(Credit::class, [$credit_role, $credit_scheme, $credit_name]);
-                }
-            }
-            if (is_array($credits_parent)) {
-                $credits_parent = array_values(array_unique($credits_parent));
-            }
-
-            // DESCRIPTION
-            if ($description_parent = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'description')) {
-                if (isset($description_parent[0]['data'])) {
-                    $description_parent = $this->sanitize($description_parent[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-            } elseif ($description_parent = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'description')) {
-                if (isset($description_parent[0]['data'])) {
-                    $description_parent = $this->sanitize($description_parent[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-            }
-
-            // DURATION
-            if ($duration_parent = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'duration')) {
-                $seconds = null;
-                $minutes = null;
-                $hours = null;
-                if (isset($duration_parent[0]['data'])) {
-                    $temp = explode(':', $this->sanitize($duration_parent[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
-                    if (sizeof($temp) > 0) {
-                        $seconds = (int) array_pop($temp);
-                    }
-                    if (sizeof($temp) > 0) {
-                        $minutes = (int) array_pop($temp);
-                        $seconds += $minutes * 60;
-                    }
-                    if (sizeof($temp) > 0) {
-                        $hours = (int) array_pop($temp);
-                        $seconds += $hours * 3600;
-                    }
-                    unset($temp);
-                    $duration_parent = $seconds;
-                }
-            }
-
-            // HASHES
-            if ($hashes_iterator = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'hash')) {
-                foreach ($hashes_iterator as $hash) {
-                    $value = null;
-                    $algo = null;
-                    if (isset($hash['data'])) {
-                        $value = $this->sanitize($hash['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($hash['attribs']['']['algo'])) {
-                        $algo = $this->sanitize($hash['attribs']['']['algo'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    } else {
-                        $algo = 'md5';
-                    }
-                    $hashes_parent[] = $algo.':'.$value;
-                }
-            } elseif ($hashes_iterator = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'hash')) {
-                foreach ($hashes_iterator as $hash) {
-                    $value = null;
-                    $algo = null;
-                    if (isset($hash['data'])) {
-                        $value = $this->sanitize($hash['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($hash['attribs']['']['algo'])) {
-                        $algo = $this->sanitize($hash['attribs']['']['algo'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    } else {
-                        $algo = 'md5';
-                    }
-                    $hashes_parent[] = $algo.':'.$value;
-                }
-            }
-            if (is_array($hashes_parent)) {
-                $hashes_parent = array_values(array_unique($hashes_parent));
-            }
-
-            // KEYWORDS
-            if ($keywords = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'keywords')) {
-                if (isset($keywords[0]['data'])) {
-                    $temp = explode(',', $this->sanitize($keywords[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
-                    foreach ($temp as $word) {
-                        $keywords_parent[] = trim($word);
-                    }
-                }
-                unset($temp);
-            } elseif ($keywords = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'keywords')) {
-                if (isset($keywords[0]['data'])) {
-                    $temp = explode(',', $this->sanitize($keywords[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
-                    foreach ($temp as $word) {
-                        $keywords_parent[] = trim($word);
-                    }
-                }
-                unset($temp);
-            } elseif ($keywords = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'keywords')) {
-                if (isset($keywords[0]['data'])) {
-                    $temp = explode(',', $this->sanitize($keywords[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
-                    foreach ($temp as $word) {
-                        $keywords_parent[] = trim($word);
-                    }
-                }
-                unset($temp);
-            } elseif ($keywords = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'keywords')) {
-                if (isset($keywords[0]['data'])) {
-                    $temp = explode(',', $this->sanitize($keywords[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
-                    foreach ($temp as $word) {
-                        $keywords_parent[] = trim($word);
-                    }
-                }
-                unset($temp);
-            }
-            if (is_array($keywords_parent)) {
-                $keywords_parent = array_values(array_unique($keywords_parent));
-            }
-
-            // PLAYER
-            if ($player_parent = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'player')) {
-                if (isset($player_parent[0]['attribs']['']['url'])) {
-                    $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-                }
-            } elseif ($player_parent = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'player')) {
-                if (isset($player_parent[0]['attribs']['']['url'])) {
-                    $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-                }
-            }
-
-            // RATINGS
-            if ($ratings = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'rating')) {
-                foreach ($ratings as $rating) {
-                    $rating_scheme = null;
-                    $rating_value = null;
-                    if (isset($rating['attribs']['']['scheme'])) {
-                        $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    } else {
-                        $rating_scheme = 'urn:simple';
-                    }
-                    if (isset($rating['data'])) {
-                        $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    $ratings_parent[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
-                }
-            } elseif ($ratings = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'explicit')) {
-                foreach ($ratings as $rating) {
-                    $rating_scheme = 'urn:itunes';
-                    $rating_value = null;
-                    if (isset($rating['data'])) {
-                        $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    $ratings_parent[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
-                }
-            } elseif ($ratings = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'rating')) {
-                foreach ($ratings as $rating) {
-                    $rating_scheme = null;
-                    $rating_value = null;
-                    if (isset($rating['attribs']['']['scheme'])) {
-                        $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    } else {
-                        $rating_scheme = 'urn:simple';
-                    }
-                    if (isset($rating['data'])) {
-                        $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    $ratings_parent[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
-                }
-            } elseif ($ratings = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'explicit')) {
-                foreach ($ratings as $rating) {
-                    $rating_scheme = 'urn:itunes';
-                    $rating_value = null;
-                    if (isset($rating['data'])) {
-                        $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    $ratings_parent[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
-                }
-            }
-            if (is_array($ratings_parent)) {
-                $ratings_parent = array_values(array_unique($ratings_parent));
-            }
-
-            // RESTRICTIONS
-            if ($restrictions = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'restriction')) {
-                foreach ($restrictions as $restriction) {
-                    $restriction_relationship = null;
-                    $restriction_type = null;
-                    $restriction_value = null;
-                    if (isset($restriction['attribs']['']['relationship'])) {
-                        $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($restriction['attribs']['']['type'])) {
-                        $restriction_type = $this->sanitize($restriction['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($restriction['data'])) {
-                        $restriction_value = $this->sanitize($restriction['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    $restrictions_parent[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
-                }
-            } elseif ($restrictions = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'block')) {
-                foreach ($restrictions as $restriction) {
-                    $restriction_relationship = 'allow';
-                    $restriction_type = null;
-                    $restriction_value = 'itunes';
-                    if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes') {
-                        $restriction_relationship = 'deny';
-                    }
-                    $restrictions_parent[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
-                }
-            } elseif ($restrictions = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'restriction')) {
-                foreach ($restrictions as $restriction) {
-                    $restriction_relationship = null;
-                    $restriction_type = null;
-                    $restriction_value = null;
-                    if (isset($restriction['attribs']['']['relationship'])) {
-                        $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($restriction['attribs']['']['type'])) {
-                        $restriction_type = $this->sanitize($restriction['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($restriction['data'])) {
-                        $restriction_value = $this->sanitize($restriction['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    $restrictions_parent[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
-                }
-            } elseif ($restrictions = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'block')) {
-                foreach ($restrictions as $restriction) {
-                    $restriction_relationship = 'allow';
-                    $restriction_type = null;
-                    $restriction_value = 'itunes';
-                    if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes') {
-                        $restriction_relationship = 'deny';
-                    }
-                    $restrictions_parent[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
-                }
-            }
-            if (is_array($restrictions_parent)) {
-                $restrictions_parent = array_values(array_unique($restrictions_parent));
-            } else {
-                $restrictions_parent = [new \SimplePie\Restriction('allow', null, 'default')];
-            }
-
-            // THUMBNAILS
-            if ($thumbnails = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'thumbnail')) {
-                foreach ($thumbnails as $thumbnail) {
-                    if (isset($thumbnail['attribs']['']['url'])) {
-                        $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-                    }
-                }
-            } elseif ($thumbnails = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'thumbnail')) {
-                foreach ($thumbnails as $thumbnail) {
-                    if (isset($thumbnail['attribs']['']['url'])) {
-                        $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-                    }
-                }
-            }
-
-            // TITLES
-            if ($title_parent = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'title')) {
-                if (isset($title_parent[0]['data'])) {
-                    $title_parent = $this->sanitize($title_parent[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-            } elseif ($title_parent = $parent->get_channel_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'title')) {
-                if (isset($title_parent[0]['data'])) {
-                    $title_parent = $this->sanitize($title_parent[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                }
-            }
-
-            // Clear the memory
-            unset($parent);
-
-            // Attributes
-            $bitrate = null;
-            $channels = null;
-            $duration = null;
-            $expression = null;
-            $framerate = null;
-            $height = null;
-            $javascript = null;
-            $lang = null;
-            $length = null;
-            $medium = null;
-            $samplingrate = null;
-            $type = null;
-            $url = null;
-            $width = null;
-
-            // Elements
-            $captions = null;
-            $categories = null;
-            $copyrights = null;
-            $credits = null;
-            $description = null;
-            $hashes = null;
-            $keywords = null;
-            $player = null;
-            $ratings = null;
-            $restrictions = null;
-            $thumbnails = null;
-            $title = null;
-
-            // If we have media:group tags, loop through them.
-            foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_MEDIARSS, 'group') as $group) {
-                if (isset($group['child']) && isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['content'])) {
-                    // If we have media:content tags, loop through them.
-                    foreach ((array) $group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['content'] as $content) {
-                        if (isset($content['attribs']['']['url'])) {
-                            // Attributes
-                            $bitrate = null;
-                            $channels = null;
-                            $duration = null;
-                            $expression = null;
-                            $framerate = null;
-                            $height = null;
-                            $javascript = null;
-                            $lang = null;
-                            $length = null;
-                            $medium = null;
-                            $samplingrate = null;
-                            $type = null;
-                            $url = null;
-                            $width = null;
-
-                            // Elements
-                            $captions = null;
-                            $categories = null;
-                            $copyrights = null;
-                            $credits = null;
-                            $description = null;
-                            $hashes = null;
-                            $keywords = null;
-                            $player = null;
-                            $ratings = null;
-                            $restrictions = null;
-                            $thumbnails = null;
-                            $title = null;
-
-                            // Start checking the attributes of media:content
-                            if (isset($content['attribs']['']['bitrate'])) {
-                                $bitrate = $this->sanitize($content['attribs']['']['bitrate'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            }
-                            if (isset($content['attribs']['']['channels'])) {
-                                $channels = $this->sanitize($content['attribs']['']['channels'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            }
-                            if (isset($content['attribs']['']['duration'])) {
-                                $duration = $this->sanitize($content['attribs']['']['duration'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            } else {
-                                $duration = $duration_parent;
-                            }
-                            if (isset($content['attribs']['']['expression'])) {
-                                $expression = $this->sanitize($content['attribs']['']['expression'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            }
-                            if (isset($content['attribs']['']['framerate'])) {
-                                $framerate = $this->sanitize($content['attribs']['']['framerate'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            }
-                            if (isset($content['attribs']['']['height'])) {
-                                $height = $this->sanitize($content['attribs']['']['height'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            }
-                            if (isset($content['attribs']['']['lang'])) {
-                                $lang = $this->sanitize($content['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            }
-                            if (isset($content['attribs']['']['fileSize'])) {
-                                $length = intval($content['attribs']['']['fileSize']);
-                            }
-                            if (isset($content['attribs']['']['medium'])) {
-                                $medium = $this->sanitize($content['attribs']['']['medium'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            }
-                            if (isset($content['attribs']['']['samplingrate'])) {
-                                $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            }
-                            if (isset($content['attribs']['']['type'])) {
-                                $type = $this->sanitize($content['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            }
-                            if (isset($content['attribs']['']['width'])) {
-                                $width = $this->sanitize($content['attribs']['']['width'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            }
-                            $url = $this->sanitize($content['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-
-                            // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
-
-                            // CAPTIONS
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['text'])) {
-                                foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['text'] as $caption) {
-                                    $caption_type = null;
-                                    $caption_lang = null;
-                                    $caption_startTime = null;
-                                    $caption_endTime = null;
-                                    $caption_text = null;
-                                    if (isset($caption['attribs']['']['type'])) {
-                                        $caption_type = $this->sanitize($caption['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($caption['attribs']['']['lang'])) {
-                                        $caption_lang = $this->sanitize($caption['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($caption['attribs']['']['start'])) {
-                                        $caption_startTime = $this->sanitize($caption['attribs']['']['start'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($caption['attribs']['']['end'])) {
-                                        $caption_endTime = $this->sanitize($caption['attribs']['']['end'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($caption['data'])) {
-                                        $caption_text = $this->sanitize($caption['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    $captions[] = $this->registry->create(Caption::class, [$caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text]);
-                                }
-                                if (is_array($captions)) {
-                                    $captions = array_values(array_unique($captions));
-                                }
-                            } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['text'])) {
-                                foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['text'] as $caption) {
-                                    $caption_type = null;
-                                    $caption_lang = null;
-                                    $caption_startTime = null;
-                                    $caption_endTime = null;
-                                    $caption_text = null;
-                                    if (isset($caption['attribs']['']['type'])) {
-                                        $caption_type = $this->sanitize($caption['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($caption['attribs']['']['lang'])) {
-                                        $caption_lang = $this->sanitize($caption['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($caption['attribs']['']['start'])) {
-                                        $caption_startTime = $this->sanitize($caption['attribs']['']['start'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($caption['attribs']['']['end'])) {
-                                        $caption_endTime = $this->sanitize($caption['attribs']['']['end'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($caption['data'])) {
-                                        $caption_text = $this->sanitize($caption['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    $captions[] = $this->registry->create(Caption::class, [$caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text]);
-                                }
-                                if (is_array($captions)) {
-                                    $captions = array_values(array_unique($captions));
-                                }
-                            } else {
-                                $captions = $captions_parent;
-                            }
-
-                            // CATEGORIES
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['category'])) {
-                                foreach ((array) $content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['category'] as $category) {
-                                    $term = null;
-                                    $scheme = null;
-                                    $label = null;
-                                    if (isset($category['data'])) {
-                                        $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($category['attribs']['']['scheme'])) {
-                                        $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    } else {
-                                        $scheme = 'http://search.yahoo.com/mrss/category_schema';
-                                    }
-                                    if (isset($category['attribs']['']['label'])) {
-                                        $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    $categories[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
-                                }
-                            }
-                            if (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['category'])) {
-                                foreach ((array) $group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['category'] as $category) {
-                                    $term = null;
-                                    $scheme = null;
-                                    $label = null;
-                                    if (isset($category['data'])) {
-                                        $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($category['attribs']['']['scheme'])) {
-                                        $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    } else {
-                                        $scheme = 'http://search.yahoo.com/mrss/category_schema';
-                                    }
-                                    if (isset($category['attribs']['']['label'])) {
-                                        $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    $categories[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
-                                }
-                            }
-                            if (is_array($categories) && is_array($categories_parent)) {
-                                $categories = array_values(array_unique(array_merge($categories, $categories_parent)));
-                            } elseif (is_array($categories)) {
-                                $categories = array_values(array_unique($categories));
-                            } elseif (is_array($categories_parent)) {
-                                $categories = array_values(array_unique($categories_parent));
-                            }
-
-                            // COPYRIGHTS
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'])) {
-                                $copyright_url = null;
-                                $copyright_label = null;
-                                if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) {
-                                    $copyright_url = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['data'])) {
-                                    $copyright_label = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                $copyrights = $this->registry->create(Copyright::class, [$copyright_url, $copyright_label]);
-                            } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'])) {
-                                $copyright_url = null;
-                                $copyright_label = null;
-                                if (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) {
-                                    $copyright_url = $this->sanitize($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                if (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['data'])) {
-                                    $copyright_label = $this->sanitize($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                $copyrights = $this->registry->create(Copyright::class, [$copyright_url, $copyright_label]);
-                            } else {
-                                $copyrights = $copyrights_parent;
-                            }
-
-                            // CREDITS
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['credit'])) {
-                                foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['credit'] as $credit) {
-                                    $credit_role = null;
-                                    $credit_scheme = null;
-                                    $credit_name = null;
-                                    if (isset($credit['attribs']['']['role'])) {
-                                        $credit_role = $this->sanitize($credit['attribs']['']['role'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($credit['attribs']['']['scheme'])) {
-                                        $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    } else {
-                                        $credit_scheme = 'urn:ebu';
-                                    }
-                                    if (isset($credit['data'])) {
-                                        $credit_name = $this->sanitize($credit['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    $credits[] = $this->registry->create(Credit::class, [$credit_role, $credit_scheme, $credit_name]);
-                                }
-                                if (is_array($credits)) {
-                                    $credits = array_values(array_unique($credits));
-                                }
-                            } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['credit'])) {
-                                foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['credit'] as $credit) {
-                                    $credit_role = null;
-                                    $credit_scheme = null;
-                                    $credit_name = null;
-                                    if (isset($credit['attribs']['']['role'])) {
-                                        $credit_role = $this->sanitize($credit['attribs']['']['role'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($credit['attribs']['']['scheme'])) {
-                                        $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    } else {
-                                        $credit_scheme = 'urn:ebu';
-                                    }
-                                    if (isset($credit['data'])) {
-                                        $credit_name = $this->sanitize($credit['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    $credits[] = $this->registry->create(Credit::class, [$credit_role, $credit_scheme, $credit_name]);
-                                }
-                                if (is_array($credits)) {
-                                    $credits = array_values(array_unique($credits));
-                                }
-                            } else {
-                                $credits = $credits_parent;
-                            }
-
-                            // DESCRIPTION
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['description'])) {
-                                $description = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['description'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['description'])) {
-                                $description = $this->sanitize($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['description'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            } else {
-                                $description = $description_parent;
-                            }
-
-                            // HASHES
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['hash'])) {
-                                foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['hash'] as $hash) {
-                                    $value = null;
-                                    $algo = null;
-                                    if (isset($hash['data'])) {
-                                        $value = $this->sanitize($hash['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($hash['attribs']['']['algo'])) {
-                                        $algo = $this->sanitize($hash['attribs']['']['algo'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    } else {
-                                        $algo = 'md5';
-                                    }
-                                    $hashes[] = $algo.':'.$value;
-                                }
-                                if (is_array($hashes)) {
-                                    $hashes = array_values(array_unique($hashes));
-                                }
-                            } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['hash'])) {
-                                foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['hash'] as $hash) {
-                                    $value = null;
-                                    $algo = null;
-                                    if (isset($hash['data'])) {
-                                        $value = $this->sanitize($hash['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($hash['attribs']['']['algo'])) {
-                                        $algo = $this->sanitize($hash['attribs']['']['algo'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    } else {
-                                        $algo = 'md5';
-                                    }
-                                    $hashes[] = $algo.':'.$value;
-                                }
-                                if (is_array($hashes)) {
-                                    $hashes = array_values(array_unique($hashes));
-                                }
-                            } else {
-                                $hashes = $hashes_parent;
-                            }
-
-                            // KEYWORDS
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'])) {
-                                if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'][0]['data'])) {
-                                    $temp = explode(',', $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
-                                    foreach ($temp as $word) {
-                                        $keywords[] = trim($word);
-                                    }
-                                    unset($temp);
-                                }
-                                if (is_array($keywords)) {
-                                    $keywords = array_values(array_unique($keywords));
-                                }
-                            } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'])) {
-                                if (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'][0]['data'])) {
-                                    $temp = explode(',', $this->sanitize($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
-                                    foreach ($temp as $word) {
-                                        $keywords[] = trim($word);
-                                    }
-                                    unset($temp);
-                                }
-                                if (is_array($keywords)) {
-                                    $keywords = array_values(array_unique($keywords));
-                                }
-                            } else {
-                                $keywords = $keywords_parent;
-                            }
-
-                            // PLAYER
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'])) {
-                                $player = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-                            } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'])) {
-                                $player = $this->sanitize($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-                            } else {
-                                $player = $player_parent;
-                            }
-
-                            // RATINGS
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['rating'])) {
-                                foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['rating'] as $rating) {
-                                    $rating_scheme = null;
-                                    $rating_value = null;
-                                    if (isset($rating['attribs']['']['scheme'])) {
-                                        $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    } else {
-                                        $rating_scheme = 'urn:simple';
-                                    }
-                                    if (isset($rating['data'])) {
-                                        $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    $ratings[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
-                                }
-                                if (is_array($ratings)) {
-                                    $ratings = array_values(array_unique($ratings));
-                                }
-                            } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['rating'])) {
-                                foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['rating'] as $rating) {
-                                    $rating_scheme = null;
-                                    $rating_value = null;
-                                    if (isset($rating['attribs']['']['scheme'])) {
-                                        $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    } else {
-                                        $rating_scheme = 'urn:simple';
-                                    }
-                                    if (isset($rating['data'])) {
-                                        $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    $ratings[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
-                                }
-                                if (is_array($ratings)) {
-                                    $ratings = array_values(array_unique($ratings));
-                                }
-                            } else {
-                                $ratings = $ratings_parent;
-                            }
-
-                            // RESTRICTIONS
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['restriction'])) {
-                                foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['restriction'] as $restriction) {
-                                    $restriction_relationship = null;
-                                    $restriction_type = null;
-                                    $restriction_value = null;
-                                    if (isset($restriction['attribs']['']['relationship'])) {
-                                        $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($restriction['attribs']['']['type'])) {
-                                        $restriction_type = $this->sanitize($restriction['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($restriction['data'])) {
-                                        $restriction_value = $this->sanitize($restriction['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    $restrictions[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
-                                }
-                                if (is_array($restrictions)) {
-                                    $restrictions = array_values(array_unique($restrictions));
-                                }
-                            } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['restriction'])) {
-                                foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['restriction'] as $restriction) {
-                                    $restriction_relationship = null;
-                                    $restriction_type = null;
-                                    $restriction_value = null;
-                                    if (isset($restriction['attribs']['']['relationship'])) {
-                                        $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($restriction['attribs']['']['type'])) {
-                                        $restriction_type = $this->sanitize($restriction['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    if (isset($restriction['data'])) {
-                                        $restriction_value = $this->sanitize($restriction['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                    }
-                                    $restrictions[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
-                                }
-                                if (is_array($restrictions)) {
-                                    $restrictions = array_values(array_unique($restrictions));
-                                }
-                            } else {
-                                $restrictions = $restrictions_parent;
-                            }
-
-                            // THUMBNAILS
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'])) {
-                                foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) {
-                                    $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-                                }
-                                if (is_array($thumbnails)) {
-                                    $thumbnails = array_values(array_unique($thumbnails));
-                                }
-                            } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'])) {
-                                foreach ($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) {
-                                    $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-                                }
-                                if (is_array($thumbnails)) {
-                                    $thumbnails = array_values(array_unique($thumbnails));
-                                }
-                            } else {
-                                $thumbnails = $thumbnails_parent;
-                            }
-
-                            // TITLES
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['title'])) {
-                                $title = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['title'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            } elseif (isset($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['title'])) {
-                                $title = $this->sanitize($group['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['title'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            } else {
-                                $title = $title_parent;
-                            }
-
-                            $this->data['enclosures'][] = $this->registry->create(Enclosure::class, [$url, $type, $length, null, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width]);
-                        }
-                    }
-                }
-            }
-
-            // If we have standalone media:content tags, loop through them.
-            if (isset($this->data['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['content'])) {
-                foreach ((array) $this->data['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['content'] as $content) {
-                    if (isset($content['attribs']['']['url']) || isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'])) {
-                        // Attributes
-                        $bitrate = null;
-                        $channels = null;
-                        $duration = null;
-                        $expression = null;
-                        $framerate = null;
-                        $height = null;
-                        $javascript = null;
-                        $lang = null;
-                        $length = null;
-                        $medium = null;
-                        $samplingrate = null;
-                        $type = null;
-                        $url = null;
-                        $width = null;
-
-                        // Elements
-                        $captions = null;
-                        $categories = null;
-                        $copyrights = null;
-                        $credits = null;
-                        $description = null;
-                        $hashes = null;
-                        $keywords = null;
-                        $player = null;
-                        $ratings = null;
-                        $restrictions = null;
-                        $thumbnails = null;
-                        $title = null;
-
-                        // Start checking the attributes of media:content
-                        if (isset($content['attribs']['']['bitrate'])) {
-                            $bitrate = $this->sanitize($content['attribs']['']['bitrate'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        }
-                        if (isset($content['attribs']['']['channels'])) {
-                            $channels = $this->sanitize($content['attribs']['']['channels'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        }
-                        if (isset($content['attribs']['']['duration'])) {
-                            $duration = $this->sanitize($content['attribs']['']['duration'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        } else {
-                            $duration = $duration_parent;
-                        }
-                        if (isset($content['attribs']['']['expression'])) {
-                            $expression = $this->sanitize($content['attribs']['']['expression'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        }
-                        if (isset($content['attribs']['']['framerate'])) {
-                            $framerate = $this->sanitize($content['attribs']['']['framerate'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        }
-                        if (isset($content['attribs']['']['height'])) {
-                            $height = $this->sanitize($content['attribs']['']['height'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        }
-                        if (isset($content['attribs']['']['lang'])) {
-                            $lang = $this->sanitize($content['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        }
-                        if (isset($content['attribs']['']['fileSize'])) {
-                            $length = intval($content['attribs']['']['fileSize']);
-                        }
-                        if (isset($content['attribs']['']['medium'])) {
-                            $medium = $this->sanitize($content['attribs']['']['medium'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        }
-                        if (isset($content['attribs']['']['samplingrate'])) {
-                            $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        }
-                        if (isset($content['attribs']['']['type'])) {
-                            $type = $this->sanitize($content['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        }
-                        if (isset($content['attribs']['']['width'])) {
-                            $width = $this->sanitize($content['attribs']['']['width'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        }
-                        if (isset($content['attribs']['']['url'])) {
-                            $url = $this->sanitize($content['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-                        }
-                        // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
-
-                        // CAPTIONS
-                        if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['text'])) {
-                            foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['text'] as $caption) {
-                                $caption_type = null;
-                                $caption_lang = null;
-                                $caption_startTime = null;
-                                $caption_endTime = null;
-                                $caption_text = null;
-                                if (isset($caption['attribs']['']['type'])) {
-                                    $caption_type = $this->sanitize($caption['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                if (isset($caption['attribs']['']['lang'])) {
-                                    $caption_lang = $this->sanitize($caption['attribs']['']['lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                if (isset($caption['attribs']['']['start'])) {
-                                    $caption_startTime = $this->sanitize($caption['attribs']['']['start'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                if (isset($caption['attribs']['']['end'])) {
-                                    $caption_endTime = $this->sanitize($caption['attribs']['']['end'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                if (isset($caption['data'])) {
-                                    $caption_text = $this->sanitize($caption['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                $captions[] = $this->registry->create(Caption::class, [$caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text]);
-                            }
-                            if (is_array($captions)) {
-                                $captions = array_values(array_unique($captions));
-                            }
-                        } else {
-                            $captions = $captions_parent;
-                        }
-
-                        // CATEGORIES
-                        if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['category'])) {
-                            foreach ((array) $content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['category'] as $category) {
-                                $term = null;
-                                $scheme = null;
-                                $label = null;
-                                if (isset($category['data'])) {
-                                    $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                if (isset($category['attribs']['']['scheme'])) {
-                                    $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                } else {
-                                    $scheme = 'http://search.yahoo.com/mrss/category_schema';
-                                }
-                                if (isset($category['attribs']['']['label'])) {
-                                    $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                $categories[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
-                            }
-                        }
-                        if (is_array($categories) && is_array($categories_parent)) {
-                            $categories = array_values(array_unique(array_merge($categories, $categories_parent)));
-                        } elseif (is_array($categories)) {
-                            $categories = array_values(array_unique($categories));
-                        } elseif (is_array($categories_parent)) {
-                            $categories = array_values(array_unique($categories_parent));
-                        } else {
-                            $categories = null;
-                        }
-
-                        // COPYRIGHTS
-                        if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'])) {
-                            $copyright_url = null;
-                            $copyright_label = null;
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) {
-                                $copyright_url = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            }
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['data'])) {
-                                $copyright_label = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['copyright'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                            }
-                            $copyrights = $this->registry->create(Copyright::class, [$copyright_url, $copyright_label]);
-                        } else {
-                            $copyrights = $copyrights_parent;
-                        }
-
-                        // CREDITS
-                        if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['credit'])) {
-                            foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['credit'] as $credit) {
-                                $credit_role = null;
-                                $credit_scheme = null;
-                                $credit_name = null;
-                                if (isset($credit['attribs']['']['role'])) {
-                                    $credit_role = $this->sanitize($credit['attribs']['']['role'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                if (isset($credit['attribs']['']['scheme'])) {
-                                    $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                } else {
-                                    $credit_scheme = 'urn:ebu';
-                                }
-                                if (isset($credit['data'])) {
-                                    $credit_name = $this->sanitize($credit['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                $credits[] = $this->registry->create(Credit::class, [$credit_role, $credit_scheme, $credit_name]);
-                            }
-                            if (is_array($credits)) {
-                                $credits = array_values(array_unique($credits));
-                            }
-                        } else {
-                            $credits = $credits_parent;
-                        }
-
-                        // DESCRIPTION
-                        if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['description'])) {
-                            $description = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['description'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        } else {
-                            $description = $description_parent;
-                        }
-
-                        // HASHES
-                        if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['hash'])) {
-                            foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['hash'] as $hash) {
-                                $value = null;
-                                $algo = null;
-                                if (isset($hash['data'])) {
-                                    $value = $this->sanitize($hash['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                if (isset($hash['attribs']['']['algo'])) {
-                                    $algo = $this->sanitize($hash['attribs']['']['algo'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                } else {
-                                    $algo = 'md5';
-                                }
-                                $hashes[] = $algo.':'.$value;
-                            }
-                            if (is_array($hashes)) {
-                                $hashes = array_values(array_unique($hashes));
-                            }
-                        } else {
-                            $hashes = $hashes_parent;
-                        }
-
-                        // KEYWORDS
-                        if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'])) {
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'][0]['data'])) {
-                                $temp = explode(',', $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['keywords'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT));
-                                foreach ($temp as $word) {
-                                    $keywords[] = trim($word);
-                                }
-                                unset($temp);
-                            }
-                            if (is_array($keywords)) {
-                                $keywords = array_values(array_unique($keywords));
-                            }
-                        } else {
-                            $keywords = $keywords_parent;
-                        }
-
-                        // PLAYER
-                        if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'])) {
-                            if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'])) {
-                                $player = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-                            }
-                        } else {
-                            $player = $player_parent;
-                        }
-
-                        // RATINGS
-                        if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['rating'])) {
-                            foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['rating'] as $rating) {
-                                $rating_scheme = null;
-                                $rating_value = null;
-                                if (isset($rating['attribs']['']['scheme'])) {
-                                    $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                } else {
-                                    $rating_scheme = 'urn:simple';
-                                }
-                                if (isset($rating['data'])) {
-                                    $rating_value = $this->sanitize($rating['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                $ratings[] = $this->registry->create(Rating::class, [$rating_scheme, $rating_value]);
-                            }
-                            if (is_array($ratings)) {
-                                $ratings = array_values(array_unique($ratings));
-                            }
-                        } else {
-                            $ratings = $ratings_parent;
-                        }
-
-                        // RESTRICTIONS
-                        if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['restriction'])) {
-                            foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['restriction'] as $restriction) {
-                                $restriction_relationship = null;
-                                $restriction_type = null;
-                                $restriction_value = null;
-                                if (isset($restriction['attribs']['']['relationship'])) {
-                                    $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                if (isset($restriction['attribs']['']['type'])) {
-                                    $restriction_type = $this->sanitize($restriction['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                if (isset($restriction['data'])) {
-                                    $restriction_value = $this->sanitize($restriction['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                                }
-                                $restrictions[] = $this->registry->create(Restriction::class, [$restriction_relationship, $restriction_type, $restriction_value]);
-                            }
-                            if (is_array($restrictions)) {
-                                $restrictions = array_values(array_unique($restrictions));
-                            }
-                        } else {
-                            $restrictions = $restrictions_parent;
-                        }
-
-                        // THUMBNAILS
-                        if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'])) {
-                            foreach ($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) {
-                                if (isset($thumbnail['attribs']['']['url'])) {
-                                    $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-                                }
-                            }
-                            if (is_array($thumbnails)) {
-                                $thumbnails = array_values(array_unique($thumbnails));
-                            }
-                        } else {
-                            $thumbnails = $thumbnails_parent;
-                        }
-
-                        // TITLES
-                        if (isset($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['title'])) {
-                            $title = $this->sanitize($content['child'][\SimplePie\SimplePie::NAMESPACE_MEDIARSS]['title'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                        } else {
-                            $title = $title_parent;
-                        }
-
-                        $this->data['enclosures'][] = $this->registry->create(Enclosure::class, [$url, $type, $length, null, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width]);
-                    }
-                }
-            }
-
-            foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'link') as $link) {
-                if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure') {
-                    // Attributes
-                    $bitrate = null;
-                    $channels = null;
-                    $duration = null;
-                    $expression = null;
-                    $framerate = null;
-                    $height = null;
-                    $javascript = null;
-                    $lang = null;
-                    $length = null;
-                    $medium = null;
-                    $samplingrate = null;
-                    $type = null;
-                    $url = null;
-                    $width = null;
-
-                    $url = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($link));
-                    if (isset($link['attribs']['']['type'])) {
-                        $type = $this->sanitize($link['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($link['attribs']['']['length'])) {
-                        $length = intval($link['attribs']['']['length']);
-                    }
-                    if (isset($link['attribs']['']['title'])) {
-                        $title = $this->sanitize($link['attribs']['']['title'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    } else {
-                        $title = $title_parent;
-                    }
-
-                    // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
-                    $this->data['enclosures'][] = $this->registry->create(Enclosure::class, [$url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title, $width]);
-                }
-            }
-
-            foreach ((array) $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'link') as $link) {
-                if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure') {
-                    // Attributes
-                    $bitrate = null;
-                    $channels = null;
-                    $duration = null;
-                    $expression = null;
-                    $framerate = null;
-                    $height = null;
-                    $javascript = null;
-                    $lang = null;
-                    $length = null;
-                    $medium = null;
-                    $samplingrate = null;
-                    $type = null;
-                    $url = null;
-                    $width = null;
-
-                    $url = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($link));
-                    if (isset($link['attribs']['']['type'])) {
-                        $type = $this->sanitize($link['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($link['attribs']['']['length'])) {
-                        $length = intval($link['attribs']['']['length']);
-                    }
-
-                    // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
-                    $this->data['enclosures'][] = $this->registry->create(Enclosure::class, [$url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width]);
-                }
-            }
-
-            foreach ($this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'enclosure') ?? [] as $enclosure) {
-                if (isset($enclosure['attribs']['']['url'])) {
-                    // Attributes
-                    $bitrate = null;
-                    $channels = null;
-                    $duration = null;
-                    $expression = null;
-                    $framerate = null;
-                    $height = null;
-                    $javascript = null;
-                    $lang = null;
-                    $length = null;
-                    $medium = null;
-                    $samplingrate = null;
-                    $type = null;
-                    $url = null;
-                    $width = null;
-
-                    $url = $this->sanitize($enclosure['attribs']['']['url'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($enclosure));
-                    $url = $this->feed->sanitize->https_url($url);
-                    if (isset($enclosure['attribs']['']['type'])) {
-                        $type = $this->sanitize($enclosure['attribs']['']['type'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-                    }
-                    if (isset($enclosure['attribs']['']['length'])) {
-                        $length = intval($enclosure['attribs']['']['length']);
-                    }
-
-                    // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
-                    $this->data['enclosures'][] = $this->registry->create(Enclosure::class, [$url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width]);
-                }
-            }
-
-            if (sizeof($this->data['enclosures']) === 0 && ($url || $type || $length || $bitrate || $captions_parent || $categories_parent || $channels || $copyrights_parent || $credits_parent || $description_parent || $duration_parent || $expression || $framerate || $hashes_parent || $height || $keywords_parent || $lang || $medium || $player_parent || $ratings_parent || $restrictions_parent || $samplingrate || $thumbnails_parent || $title_parent || $width)) {
-                // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
-                $this->data['enclosures'][] = $this->registry->create(Enclosure::class, [$url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width]);
-            }
-
-            $this->data['enclosures'] = array_values(array_unique($this->data['enclosures']));
-        }
-        if (!empty($this->data['enclosures'])) {
-            return $this->data['enclosures'];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the latitude coordinates for the item
-     *
-     * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
-     *
-     * Uses `<geo:lat>` or `<georss:point>`
-     *
-     * @since 1.0
-     * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
-     * @link http://www.georss.org/ GeoRSS
-     * @return string|null
-     */
-    public function get_latitude()
-    {
-        if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_W3C_BASIC_GEO, 'lat')) {
-            return (float) $return[0]['data'];
-        } elseif (($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) {
-            return (float) $match[1];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the longitude coordinates for the item
-     *
-     * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
-     *
-     * Uses `<geo:long>`, `<geo:lon>` or `<georss:point>`
-     *
-     * @since 1.0
-     * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
-     * @link http://www.georss.org/ GeoRSS
-     * @return string|null
-     */
-    public function get_longitude()
-    {
-        if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_W3C_BASIC_GEO, 'long')) {
-            return (float) $return[0]['data'];
-        } elseif ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_W3C_BASIC_GEO, 'lon')) {
-            return (float) $return[0]['data'];
-        } elseif (($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) {
-            return (float) $match[2];
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the `<atom:source>` for the item
-     *
-     * @since 1.1
-     * @return \SimplePie\Source|null
-     */
-    public function get_source()
-    {
-        if ($return = $this->get_item_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'source')) {
-            return $this->registry->create(Source::class, [$this, $return[0]]);
-        }
-
-        return null;
-    }
-}
-
-class_alias('SimplePie\Item', 'SimplePie_Item');
-
-}
-
-namespace SimplePie {
-
-/**
- * Used for feed auto-discovery
- *
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_locator_class()}
- *
- * @package SimplePie
- */
-class Locator implements RegistryAware
-{
-    public $useragent;
-    public $timeout;
-    public $file;
-    public $local = [];
-    public $elsewhere = [];
-    public $cached_entities = [];
-    public $http_base;
-    public $base;
-    public $base_location = 0;
-    public $checked_feeds = 0;
-    public $max_checked_feeds = 10;
-    public $force_fsockopen = false;
-    public $curl_options = [];
-    public $dom;
-    protected $registry;
-
-    public function __construct(\SimplePie\File $file, $timeout = 10, $useragent = null, $max_checked_feeds = 10, $force_fsockopen = false, $curl_options = [])
-    {
-        $this->file = $file;
-        $this->useragent = $useragent;
-        $this->timeout = $timeout;
-        $this->max_checked_feeds = $max_checked_feeds;
-        $this->force_fsockopen = $force_fsockopen;
-        $this->curl_options = $curl_options;
-
-        if (class_exists('DOMDocument') && $this->file->body != '') {
-            $this->dom = new \DOMDocument();
-
-            set_error_handler(['SimplePie\Misc', 'silence_errors']);
-            try {
-                $this->dom->loadHTML($this->file->body);
-            } catch (\Throwable $ex) {
-                $this->dom = null;
-            }
-            restore_error_handler();
-        } else {
-            $this->dom = null;
-        }
-    }
-
-    public function set_registry(\SimplePie\Registry $registry)/* : void */
-    {
-        $this->registry = $registry;
-    }
-
-    public function find($type = \SimplePie\SimplePie::LOCATOR_ALL, &$working = null)
-    {
-        if ($this->is_feed($this->file)) {
-            return $this->file;
-        }
-
-        if ($this->file->method & \SimplePie\SimplePie::FILE_SOURCE_REMOTE) {
-            $sniffer = $this->registry->create(Content\Type\Sniffer::class, [$this->file]);
-            if ($sniffer->get_type() !== 'text/html') {
-                return null;
-            }
-        }
-
-        if ($type & ~\SimplePie\SimplePie::LOCATOR_NONE) {
-            $this->get_base();
-        }
-
-        if ($type & \SimplePie\SimplePie::LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery()) {
-            return $working[0];
-        }
-
-        if ($type & (\SimplePie\SimplePie::LOCATOR_LOCAL_EXTENSION | \SimplePie\SimplePie::LOCATOR_LOCAL_BODY | \SimplePie\SimplePie::LOCATOR_REMOTE_EXTENSION | \SimplePie\SimplePie::LOCATOR_REMOTE_BODY) && $this->get_links()) {
-            if ($type & \SimplePie\SimplePie::LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local)) {
-                return $working[0];
-            }
-
-            if ($type & \SimplePie\SimplePie::LOCATOR_LOCAL_BODY && $working = $this->body($this->local)) {
-                return $working[0];
-            }
-
-            if ($type & \SimplePie\SimplePie::LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere)) {
-                return $working[0];
-            }
-
-            if ($type & \SimplePie\SimplePie::LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere)) {
-                return $working[0];
-            }
-        }
-        return null;
-    }
-
-    public function is_feed($file, $check_html = false)
-    {
-        if ($file->method & \SimplePie\SimplePie::FILE_SOURCE_REMOTE) {
-            $sniffer = $this->registry->create(Content\Type\Sniffer::class, [$file]);
-            $sniffed = $sniffer->get_type();
-            $mime_types = ['application/rss+xml', 'application/rdf+xml',
-                                'text/rdf', 'application/atom+xml', 'text/xml',
-                                'application/xml', 'application/x-rss+xml'];
-            if ($check_html) {
-                $mime_types[] = 'text/html';
-            }
-
-            return in_array($sniffed, $mime_types);
-        } elseif ($file->method & \SimplePie\SimplePie::FILE_SOURCE_LOCAL) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    public function get_base()
-    {
-        if ($this->dom === null) {
-            throw new \SimplePie\Exception('DOMDocument not found, unable to use locator');
-        }
-        $this->http_base = $this->file->url;
-        $this->base = $this->http_base;
-        $elements = $this->dom->getElementsByTagName('base');
-        foreach ($elements as $element) {
-            if ($element->hasAttribute('href')) {
-                $base = $this->registry->call(Misc::class, 'absolutize_url', [trim($element->getAttribute('href')), $this->http_base]);
-                if ($base === false) {
-                    continue;
-                }
-                $this->base = $base;
-                $this->base_location = method_exists($element, 'getLineNo') ? $element->getLineNo() : 0;
-                break;
-            }
-        }
-    }
-
-    public function autodiscovery()
-    {
-        $done = [];
-        $feeds = [];
-        $feeds = array_merge($feeds, $this->search_elements_by_tag('link', $done, $feeds));
-        $feeds = array_merge($feeds, $this->search_elements_by_tag('a', $done, $feeds));
-        $feeds = array_merge($feeds, $this->search_elements_by_tag('area', $done, $feeds));
-
-        if (!empty($feeds)) {
-            return array_values($feeds);
-        }
-
-        return null;
-    }
-
-    protected function search_elements_by_tag($name, &$done, $feeds)
-    {
-        if ($this->dom === null) {
-            throw new \SimplePie\Exception('DOMDocument not found, unable to use locator');
-        }
-
-        $links = $this->dom->getElementsByTagName($name);
-        foreach ($links as $link) {
-            if ($this->checked_feeds === $this->max_checked_feeds) {
-                break;
-            }
-            if ($link->hasAttribute('href') && $link->hasAttribute('rel')) {
-                $rel = array_unique($this->registry->call(Misc::class, 'space_separated_tokens', [strtolower($link->getAttribute('rel'))]));
-                $line = method_exists($link, 'getLineNo') ? $link->getLineNo() : 1;
-
-                if ($this->base_location < $line) {
-                    $href = $this->registry->call(Misc::class, 'absolutize_url', [trim($link->getAttribute('href')), $this->base]);
-                } else {
-                    $href = $this->registry->call(Misc::class, 'absolutize_url', [trim($link->getAttribute('href')), $this->http_base]);
-                }
-                if ($href === false) {
-                    continue;
-                }
-
-                if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !in_array('stylesheet', $rel) && $link->hasAttribute('type') && in_array(strtolower($this->registry->call(Misc::class, 'parse_mime', [$link->getAttribute('type')])), ['text/html', 'application/rss+xml', 'application/atom+xml'])) && !isset($feeds[$href])) {
-                    $this->checked_feeds++;
-                    $headers = [
-                        'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
-                    ];
-                    $feed = $this->registry->create(File::class, [$href, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options]);
-                    if ($feed->success && ($feed->method & \SimplePie\SimplePie::FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed, true)) {
-                        $feeds[$href] = $feed;
-                    }
-                }
-                $done[] = $href;
-            }
-        }
-
-        return $feeds;
-    }
-
-    public function get_links()
-    {
-        if ($this->dom === null) {
-            throw new \SimplePie\Exception('DOMDocument not found, unable to use locator');
-        }
-
-        $links = $this->dom->getElementsByTagName('a');
-        foreach ($links as $link) {
-            if ($link->hasAttribute('href')) {
-                $href = trim($link->getAttribute('href'));
-                $parsed = $this->registry->call(Misc::class, 'parse_url', [$href]);
-                if ($parsed['scheme'] === '' || preg_match('/^(https?|feed)?$/i', $parsed['scheme'])) {
-                    if (method_exists($link, 'getLineNo') && $this->base_location < $link->getLineNo()) {
-                        $href = $this->registry->call(Misc::class, 'absolutize_url', [trim($link->getAttribute('href')), $this->base]);
-                    } else {
-                        $href = $this->registry->call(Misc::class, 'absolutize_url', [trim($link->getAttribute('href')), $this->http_base]);
-                    }
-                    if ($href === false) {
-                        continue;
-                    }
-
-                    $current = $this->registry->call(Misc::class, 'parse_url', [$this->file->url]);
-
-                    if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority']) {
-                        $this->local[] = $href;
-                    } else {
-                        $this->elsewhere[] = $href;
-                    }
-                }
-            }
-        }
-        $this->local = array_unique($this->local);
-        $this->elsewhere = array_unique($this->elsewhere);
-        if (!empty($this->local) || !empty($this->elsewhere)) {
-            return true;
-        }
-        return null;
-    }
-
-    public function get_rel_link($rel)
-    {
-        if ($this->dom === null) {
-            throw new \SimplePie\Exception('DOMDocument not found, unable to use '.
-                                          'locator');
-        }
-        if (!class_exists('DOMXpath')) {
-            throw new \SimplePie\Exception('DOMXpath not found, unable to use '.
-                                          'get_rel_link');
-        }
-
-        $xpath = new \DOMXpath($this->dom);
-        $query = '//a[@rel and @href] | //link[@rel and @href]';
-        foreach ($xpath->query($query) as $link) {
-            $href = trim($link->getAttribute('href'));
-            $parsed = $this->registry->call(Misc::class, 'parse_url', [$href]);
-            if ($parsed['scheme'] === '' ||
-                preg_match('/^https?$/i', $parsed['scheme'])) {
-                if (method_exists($link, 'getLineNo') &&
-                    $this->base_location < $link->getLineNo()) {
-                    $href = $this->registry->call(
-                        Misc::class,
-                        'absolutize_url',
-                        [trim($link->getAttribute('href')), $this->base]
-                    );
-                } else {
-                    $href = $this->registry->call(
-                        Misc::class,
-                        'absolutize_url',
-                        [trim($link->getAttribute('href')), $this->http_base]
-                    );
-                }
-                if ($href === false) {
-                    return null;
-                }
-                $rel_values = explode(' ', strtolower($link->getAttribute('rel')));
-                if (in_array($rel, $rel_values)) {
-                    return $href;
-                }
-            }
-        }
-        return null;
-    }
-
-    public function extension(&$array)
-    {
-        foreach ($array as $key => $value) {
-            if ($this->checked_feeds === $this->max_checked_feeds) {
-                break;
-            }
-            if (in_array(strtolower(strrchr($value, '.')), ['.rss', '.rdf', '.atom', '.xml'])) {
-                $this->checked_feeds++;
-
-                $headers = [
-                    'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
-                ];
-                $feed = $this->registry->create(File::class, [$value, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options]);
-                if ($feed->success && ($feed->method & \SimplePie\SimplePie::FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) {
-                    return [$feed];
-                } else {
-                    unset($array[$key]);
-                }
-            }
-        }
-        return null;
-    }
-
-    public function body(&$array)
-    {
-        foreach ($array as $key => $value) {
-            if ($this->checked_feeds === $this->max_checked_feeds) {
-                break;
-            }
-            if (preg_match('/(feed|rss|rdf|atom|xml)/i', $value)) {
-                $this->checked_feeds++;
-                $headers = [
-                    'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
-                ];
-                $feed = $this->registry->create(File::class, [$value, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen, $this->curl_options]);
-                if ($feed->success && ($feed->method & \SimplePie\SimplePie::FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) {
-                    return [$feed];
-                } else {
-                    unset($array[$key]);
-                }
-            }
-        }
-        return null;
-    }
-}
-
-class_alias('SimplePie\Locator', 'SimplePie_Locator', false);
-
-}
-
-namespace SimplePie {
-
-use SimplePie\XML\Declaration\Parser;
-
-/**
- * Miscellaneous utilities
- *
- * @package SimplePie
- */
-class Misc
-{
-    private static $SIMPLEPIE_BUILD = null;
-
-    public static function time_hms($seconds)
-    {
-        $time = '';
-
-        $hours = floor($seconds / 3600);
-        $remainder = $seconds % 3600;
-        if ($hours > 0) {
-            $time .= $hours.':';
-        }
-
-        $minutes = floor($remainder / 60);
-        $seconds = $remainder % 60;
-        if ($minutes < 10 && $hours > 0) {
-            $minutes = '0' . $minutes;
-        }
-        if ($seconds < 10) {
-            $seconds = '0' . $seconds;
-        }
-
-        $time .= $minutes.':';
-        $time .= $seconds;
-
-        return $time;
-    }
-
-    public static function absolutize_url($relative, $base)
-    {
-        $iri = \SimplePie\IRI::absolutize(new \SimplePie\IRI($base), $relative);
-        if ($iri === false) {
-            return false;
-        }
-        return $iri->get_uri();
-    }
-
-    /**
-     * Get a HTML/XML element from a HTML string
-     *
-     * @deprecated since SimplePie 1.3, use DOMDocument instead (parsing HTML with regex is bad!)
-     * @param string $realname Element name (including namespace prefix if applicable)
-     * @param string $string HTML document
-     * @return array
-     */
-    public static function get_element($realname, $string)
-    {
-        // trigger_error(sprintf('Using method "' . __METHOD__ . '" is deprecated since SimplePie 1.3, use "DOMDocument" instead.'), \E_USER_DEPRECATED);
-
-        $return = [];
-        $name = preg_quote($realname, '/');
-        if (preg_match_all("/<($name)" . \SimplePie\SimplePie::PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
-            for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++) {
-                $return[$i]['tag'] = $realname;
-                $return[$i]['full'] = $matches[$i][0][0];
-                $return[$i]['offset'] = $matches[$i][0][1];
-                if (strlen($matches[$i][3][0]) <= 2) {
-                    $return[$i]['self_closing'] = true;
-                } else {
-                    $return[$i]['self_closing'] = false;
-                    $return[$i]['content'] = $matches[$i][4][0];
-                }
-                $return[$i]['attribs'] = [];
-                if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER)) {
-                    for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++) {
-                        if (count($attribs[$j]) === 2) {
-                            $attribs[$j][2] = $attribs[$j][1];
-                        }
-                        $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = Misc::entities_decode(end($attribs[$j]));
-                    }
-                }
-            }
-        }
-        return $return;
-    }
-
-    public static function element_implode($element)
-    {
-        $full = "<$element[tag]";
-        foreach ($element['attribs'] as $key => $value) {
-            $key = strtolower($key);
-            $full .= " $key=\"" . htmlspecialchars($value['data'], ENT_COMPAT, 'UTF-8') . '"';
-        }
-        if ($element['self_closing']) {
-            $full .= ' />';
-        } else {
-            $full .= ">$element[content]</$element[tag]>";
-        }
-        return $full;
-    }
-
-    public static function error($message, $level, $file, $line)
-    {
-        if ((error_reporting() & $level) > 0) {
-            switch ($level) {
-                case E_USER_ERROR:
-                    $note = 'PHP Error';
-                    break;
-                case E_USER_WARNING:
-                    $note = 'PHP Warning';
-                    break;
-                case E_USER_NOTICE:
-                    $note = 'PHP Notice';
-                    break;
-                default:
-                    $note = 'Unknown Error';
-                    break;
-            }
-
-            $log_error = true;
-            if (!function_exists('error_log')) {
-                $log_error = false;
-            }
-
-            $log_file = @ini_get('error_log');
-            if (!empty($log_file) && ('syslog' !== $log_file) && !@is_writable($log_file)) {
-                $log_error = false;
-            }
-
-            if ($log_error) {
-                @error_log("$note: $message in $file on line $line", 0);
-            }
-        }
-
-        return $message;
-    }
-
-    public static function fix_protocol($url, $http = 1)
-    {
-        $url = Misc::normalize_url($url);
-        $parsed = Misc::parse_url($url);
-        if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https') {
-            return Misc::fix_protocol(Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
-        }
-
-        if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url)) {
-            return Misc::fix_protocol(Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
-        }
-
-        if ($http === 2 && $parsed['scheme'] !== '') {
-            return "feed:$url";
-        } elseif ($http === 3 && strtolower($parsed['scheme']) === 'http') {
-            return substr_replace($url, 'podcast', 0, 4);
-        } elseif ($http === 4 && strtolower($parsed['scheme']) === 'http') {
-            return substr_replace($url, 'itpc', 0, 4);
-        }
-
-        return $url;
-    }
-
-    /**
-     * @deprecated since SimplePie 1.8.0, use PHP native array_replace_recursive() instead.
-     */
-    public static function array_merge_recursive($array1, $array2)
-    {
-        foreach ($array2 as $key => $value) {
-            if (is_array($value)) {
-                $array1[$key] = Misc::array_merge_recursive($array1[$key], $value);
-            } else {
-                $array1[$key] = $value;
-            }
-        }
-
-        return $array1;
-    }
-
-    public static function parse_url($url)
-    {
-        $iri = new \SimplePie\IRI($url);
-        return [
-            'scheme' => (string) $iri->scheme,
-            'authority' => (string) $iri->authority,
-            'path' => (string) $iri->path,
-            'query' => (string) $iri->query,
-            'fragment' => (string) $iri->fragment
-        ];
-    }
-
-    public static function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
-    {
-        $iri = new \SimplePie\IRI('');
-        $iri->scheme = $scheme;
-        $iri->authority = $authority;
-        $iri->path = $path;
-        $iri->query = $query;
-        $iri->fragment = $fragment;
-        return $iri->get_uri();
-    }
-
-    public static function normalize_url($url)
-    {
-        $iri = new \SimplePie\IRI($url);
-        return $iri->get_uri();
-    }
-
-    public static function percent_encoding_normalization($match)
-    {
-        $integer = hexdec($match[1]);
-        if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E) {
-            return chr($integer);
-        }
-
-        return strtoupper($match[0]);
-    }
-
-    /**
-     * Converts a Windows-1252 encoded string to a UTF-8 encoded string
-     *
-     * @static
-     * @param string $string Windows-1252 encoded string
-     * @return string UTF-8 encoded string
-     */
-    public static function windows_1252_to_utf8($string)
-    {
-        static $convert_table = ["\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF"];
-
-        return strtr($string, $convert_table);
-    }
-
-    /**
-     * Change a string from one encoding to another
-     *
-     * @param string $data Raw data in $input encoding
-     * @param string $input Encoding of $data
-     * @param string $output Encoding you want
-     * @return string|boolean False if we can't convert it
-     */
-    public static function change_encoding($data, $input, $output)
-    {
-        $input = Misc::encoding($input);
-        $output = Misc::encoding($output);
-
-        // We fail to fail on non US-ASCII bytes
-        if ($input === 'US-ASCII') {
-            static $non_ascii_octects = '';
-            if (!$non_ascii_octects) {
-                for ($i = 0x80; $i <= 0xFF; $i++) {
-                    $non_ascii_octects .= chr($i);
-                }
-            }
-            $data = substr($data, 0, strcspn($data, $non_ascii_octects));
-        }
-
-        // This is first, as behaviour of this is completely predictable
-        if ($input === 'windows-1252' && $output === 'UTF-8') {
-            return Misc::windows_1252_to_utf8($data);
-        }
-        // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
-        elseif (function_exists('mb_convert_encoding') && ($return = Misc::change_encoding_mbstring($data, $input, $output))) {
-            return $return;
-        }
-        // This is third, as behaviour of this varies with OS userland and PHP version
-        elseif (function_exists('iconv') && ($return = Misc::change_encoding_iconv($data, $input, $output))) {
-            return $return;
-        }
-        // This is last, as behaviour of this varies with OS userland and PHP version
-        elseif (class_exists('\UConverter') && ($return = Misc::change_encoding_uconverter($data, $input, $output))) {
-            return $return;
-        }
-
-        // If we can't do anything, just fail
-        return false;
-    }
-
-    protected static function change_encoding_mbstring($data, $input, $output)
-    {
-        if ($input === 'windows-949') {
-            $input = 'EUC-KR';
-        }
-        if ($output === 'windows-949') {
-            $output = 'EUC-KR';
-        }
-        if ($input === 'Windows-31J') {
-            $input = 'SJIS';
-        }
-        if ($output === 'Windows-31J') {
-            $output = 'SJIS';
-        }
-
-        // Check that the encoding is supported
-        if (!in_array($input, mb_list_encodings())) {
-            return false;
-        }
-
-        if (@mb_convert_encoding("\x80", 'UTF-16BE', $input) === "\x00\x80") {
-            return false;
-        }
-
-        // Let's do some conversion
-        if ($return = @mb_convert_encoding($data, $output, $input)) {
-            return $return;
-        }
-
-        return false;
-    }
-
-    protected static function change_encoding_iconv($data, $input, $output)
-    {
-        return @iconv($input, $output, $data);
-    }
-
-    /**
-     * @param string $data
-     * @param string $input
-     * @param string $output
-     * @return string|false
-     */
-    protected static function change_encoding_uconverter($data, $input, $output)
-    {
-        return @\UConverter::transcode($data, $output, $input);
-    }
-
-    /**
-     * Normalize an encoding name
-     *
-     * This is automatically generated by create.php
-     *
-     * To generate it, run `php create.php` on the command line, and copy the
-     * output to replace this function.
-     *
-     * @param string $charset Character set to standardise
-     * @return string Standardised name
-     */
-    public static function encoding($charset)
-    {
-        // Normalization from UTS #22
-        switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset))) {
-            case 'adobestandardencoding':
-            case 'csadobestandardencoding':
-                return 'Adobe-Standard-Encoding';
-
-            case 'adobesymbolencoding':
-            case 'cshppsmath':
-                return 'Adobe-Symbol-Encoding';
-
-            case 'ami1251':
-            case 'amiga1251':
-                return 'Amiga-1251';
-
-            case 'ansix31101983':
-            case 'csat5001983':
-            case 'csiso99naplps':
-            case 'isoir99':
-            case 'naplps':
-                return 'ANSI_X3.110-1983';
-
-            case 'arabic7':
-            case 'asmo449':
-            case 'csiso89asmo449':
-            case 'iso9036':
-            case 'isoir89':
-                return 'ASMO_449';
-
-            case 'big5':
-            case 'csbig5':
-                return 'Big5';
-
-            case 'big5hkscs':
-                return 'Big5-HKSCS';
-
-            case 'bocu1':
-            case 'csbocu1':
-                return 'BOCU-1';
-
-            case 'brf':
-            case 'csbrf':
-                return 'BRF';
-
-            case 'bs4730':
-            case 'csiso4unitedkingdom':
-            case 'gb':
-            case 'iso646gb':
-            case 'isoir4':
-            case 'uk':
-                return 'BS_4730';
-
-            case 'bsviewdata':
-            case 'csiso47bsviewdata':
-            case 'isoir47':
-                return 'BS_viewdata';
-
-            case 'cesu8':
-            case 'cscesu8':
-                return 'CESU-8';
-
-            case 'ca':
-            case 'csa71':
-            case 'csaz243419851':
-            case 'csiso121canadian1':
-            case 'iso646ca':
-            case 'isoir121':
-                return 'CSA_Z243.4-1985-1';
-
-            case 'csa72':
-            case 'csaz243419852':
-            case 'csiso122canadian2':
-            case 'iso646ca2':
-            case 'isoir122':
-                return 'CSA_Z243.4-1985-2';
-
-            case 'csaz24341985gr':
-            case 'csiso123csaz24341985gr':
-            case 'isoir123':
-                return 'CSA_Z243.4-1985-gr';
-
-            case 'csiso139csn369103':
-            case 'csn369103':
-            case 'isoir139':
-                return 'CSN_369103';
-
-            case 'csdecmcs':
-            case 'dec':
-            case 'decmcs':
-                return 'DEC-MCS';
-
-            case 'csiso21german':
-            case 'de':
-            case 'din66003':
-            case 'iso646de':
-            case 'isoir21':
-                return 'DIN_66003';
-
-            case 'csdkus':
-            case 'dkus':
-                return 'dk-us';
-
-            case 'csiso646danish':
-            case 'dk':
-            case 'ds2089':
-            case 'iso646dk':
-                return 'DS_2089';
-
-            case 'csibmebcdicatde':
-            case 'ebcdicatde':
-                return 'EBCDIC-AT-DE';
-
-            case 'csebcdicatdea':
-            case 'ebcdicatdea':
-                return 'EBCDIC-AT-DE-A';
-
-            case 'csebcdiccafr':
-            case 'ebcdiccafr':
-                return 'EBCDIC-CA-FR';
-
-            case 'csebcdicdkno':
-            case 'ebcdicdkno':
-                return 'EBCDIC-DK-NO';
-
-            case 'csebcdicdknoa':
-            case 'ebcdicdknoa':
-                return 'EBCDIC-DK-NO-A';
-
-            case 'csebcdices':
-            case 'ebcdices':
-                return 'EBCDIC-ES';
-
-            case 'csebcdicesa':
-            case 'ebcdicesa':
-                return 'EBCDIC-ES-A';
-
-            case 'csebcdicess':
-            case 'ebcdicess':
-                return 'EBCDIC-ES-S';
-
-            case 'csebcdicfise':
-            case 'ebcdicfise':
-                return 'EBCDIC-FI-SE';
-
-            case 'csebcdicfisea':
-            case 'ebcdicfisea':
-                return 'EBCDIC-FI-SE-A';
-
-            case 'csebcdicfr':
-            case 'ebcdicfr':
-                return 'EBCDIC-FR';
-
-            case 'csebcdicit':
-            case 'ebcdicit':
-                return 'EBCDIC-IT';
-
-            case 'csebcdicpt':
-            case 'ebcdicpt':
-                return 'EBCDIC-PT';
-
-            case 'csebcdicuk':
-            case 'ebcdicuk':
-                return 'EBCDIC-UK';
-
-            case 'csebcdicus':
-            case 'ebcdicus':
-                return 'EBCDIC-US';
-
-            case 'csiso111ecmacyrillic':
-            case 'ecmacyrillic':
-            case 'isoir111':
-            case 'koi8e':
-                return 'ECMA-cyrillic';
-
-            case 'csiso17spanish':
-            case 'es':
-            case 'iso646es':
-            case 'isoir17':
-                return 'ES';
-
-            case 'csiso85spanish2':
-            case 'es2':
-            case 'iso646es2':
-            case 'isoir85':
-                return 'ES2';
-
-            case 'cseucpkdfmtjapanese':
-            case 'eucjp':
-            case 'extendedunixcodepackedformatforjapanese':
-                return 'EUC-JP';
-
-            case 'cseucfixwidjapanese':
-            case 'extendedunixcodefixedwidthforjapanese':
-                return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
-
-            case 'gb18030':
-                return 'GB18030';
-
-            case 'chinese':
-            case 'cp936':
-            case 'csgb2312':
-            case 'csiso58gb231280':
-            case 'gb2312':
-            case 'gb231280':
-            case 'gbk':
-            case 'isoir58':
-            case 'ms936':
-            case 'windows936':
-                return 'GBK';
-
-            case 'cn':
-            case 'csiso57gb1988':
-            case 'gb198880':
-            case 'iso646cn':
-            case 'isoir57':
-                return 'GB_1988-80';
-
-            case 'csiso153gost1976874':
-            case 'gost1976874':
-            case 'isoir153':
-            case 'stsev35888':
-                return 'GOST_19768-74';
-
-            case 'csiso150':
-            case 'csiso150greekccitt':
-            case 'greekccitt':
-            case 'isoir150':
-                return 'greek-ccitt';
-
-            case 'csiso88greek7':
-            case 'greek7':
-            case 'isoir88':
-                return 'greek7';
-
-            case 'csiso18greek7old':
-            case 'greek7old':
-            case 'isoir18':
-                return 'greek7-old';
-
-            case 'cshpdesktop':
-            case 'hpdesktop':
-                return 'HP-DeskTop';
-
-            case 'cshplegal':
-            case 'hplegal':
-                return 'HP-Legal';
-
-            case 'cshpmath8':
-            case 'hpmath8':
-                return 'HP-Math8';
-
-            case 'cshppifont':
-            case 'hppifont':
-                return 'HP-Pi-font';
-
-            case 'cshproman8':
-            case 'hproman8':
-            case 'r8':
-            case 'roman8':
-                return 'hp-roman8';
-
-            case 'hzgb2312':
-                return 'HZ-GB-2312';
-
-            case 'csibmsymbols':
-            case 'ibmsymbols':
-                return 'IBM-Symbols';
-
-            case 'csibmthai':
-            case 'ibmthai':
-                return 'IBM-Thai';
-
-            case 'cp37':
-            case 'csibm37':
-            case 'ebcdiccpca':
-            case 'ebcdiccpnl':
-            case 'ebcdiccpus':
-            case 'ebcdiccpwt':
-            case 'ibm37':
-                return 'IBM037';
-
-            case 'cp38':
-            case 'csibm38':
-            case 'ebcdicint':
-            case 'ibm38':
-                return 'IBM038';
-
-            case 'cp273':
-            case 'csibm273':
-            case 'ibm273':
-                return 'IBM273';
-
-            case 'cp274':
-            case 'csibm274':
-            case 'ebcdicbe':
-            case 'ibm274':
-                return 'IBM274';
-
-            case 'cp275':
-            case 'csibm275':
-            case 'ebcdicbr':
-            case 'ibm275':
-                return 'IBM275';
-
-            case 'csibm277':
-            case 'ebcdiccpdk':
-            case 'ebcdiccpno':
-            case 'ibm277':
-                return 'IBM277';
-
-            case 'cp278':
-            case 'csibm278':
-            case 'ebcdiccpfi':
-            case 'ebcdiccpse':
-            case 'ibm278':
-                return 'IBM278';
-
-            case 'cp280':
-            case 'csibm280':
-            case 'ebcdiccpit':
-            case 'ibm280':
-                return 'IBM280';
-
-            case 'cp281':
-            case 'csibm281':
-            case 'ebcdicjpe':
-            case 'ibm281':
-                return 'IBM281';
-
-            case 'cp284':
-            case 'csibm284':
-            case 'ebcdiccpes':
-            case 'ibm284':
-                return 'IBM284';
-
-            case 'cp285':
-            case 'csibm285':
-            case 'ebcdiccpgb':
-            case 'ibm285':
-                return 'IBM285';
-
-            case 'cp290':
-            case 'csibm290':
-            case 'ebcdicjpkana':
-            case 'ibm290':
-                return 'IBM290';
-
-            case 'cp297':
-            case 'csibm297':
-            case 'ebcdiccpfr':
-            case 'ibm297':
-                return 'IBM297';
-
-            case 'cp420':
-            case 'csibm420':
-            case 'ebcdiccpar1':
-            case 'ibm420':
-                return 'IBM420';
-
-            case 'cp423':
-            case 'csibm423':
-            case 'ebcdiccpgr':
-            case 'ibm423':
-                return 'IBM423';
-
-            case 'cp424':
-            case 'csibm424':
-            case 'ebcdiccphe':
-            case 'ibm424':
-                return 'IBM424';
-
-            case '437':
-            case 'cp437':
-            case 'cspc8codepage437':
-            case 'ibm437':
-                return 'IBM437';
-
-            case 'cp500':
-            case 'csibm500':
-            case 'ebcdiccpbe':
-            case 'ebcdiccpch':
-            case 'ibm500':
-                return 'IBM500';
-
-            case 'cp775':
-            case 'cspc775baltic':
-            case 'ibm775':
-                return 'IBM775';
-
-            case '850':
-            case 'cp850':
-            case 'cspc850multilingual':
-            case 'ibm850':
-                return 'IBM850';
-
-            case '851':
-            case 'cp851':
-            case 'csibm851':
-            case 'ibm851':
-                return 'IBM851';
-
-            case '852':
-            case 'cp852':
-            case 'cspcp852':
-            case 'ibm852':
-                return 'IBM852';
-
-            case '855':
-            case 'cp855':
-            case 'csibm855':
-            case 'ibm855':
-                return 'IBM855';
-
-            case '857':
-            case 'cp857':
-            case 'csibm857':
-            case 'ibm857':
-                return 'IBM857';
-
-            case 'ccsid858':
-            case 'cp858':
-            case 'ibm858':
-            case 'pcmultilingual850euro':
-                return 'IBM00858';
-
-            case '860':
-            case 'cp860':
-            case 'csibm860':
-            case 'ibm860':
-                return 'IBM860';
-
-            case '861':
-            case 'cp861':
-            case 'cpis':
-            case 'csibm861':
-            case 'ibm861':
-                return 'IBM861';
-
-            case '862':
-            case 'cp862':
-            case 'cspc862latinhebrew':
-            case 'ibm862':
-                return 'IBM862';
-
-            case '863':
-            case 'cp863':
-            case 'csibm863':
-            case 'ibm863':
-                return 'IBM863';
-
-            case 'cp864':
-            case 'csibm864':
-            case 'ibm864':
-                return 'IBM864';
-
-            case '865':
-            case 'cp865':
-            case 'csibm865':
-            case 'ibm865':
-                return 'IBM865';
-
-            case '866':
-            case 'cp866':
-            case 'csibm866':
-            case 'ibm866':
-                return 'IBM866';
-
-            case 'cp868':
-            case 'cpar':
-            case 'csibm868':
-            case 'ibm868':
-                return 'IBM868';
-
-            case '869':
-            case 'cp869':
-            case 'cpgr':
-            case 'csibm869':
-            case 'ibm869':
-                return 'IBM869';
-
-            case 'cp870':
-            case 'csibm870':
-            case 'ebcdiccproece':
-            case 'ebcdiccpyu':
-            case 'ibm870':
-                return 'IBM870';
-
-            case 'cp871':
-            case 'csibm871':
-            case 'ebcdiccpis':
-            case 'ibm871':
-                return 'IBM871';
-
-            case 'cp880':
-            case 'csibm880':
-            case 'ebcdiccyrillic':
-            case 'ibm880':
-                return 'IBM880';
-
-            case 'cp891':
-            case 'csibm891':
-            case 'ibm891':
-                return 'IBM891';
-
-            case 'cp903':
-            case 'csibm903':
-            case 'ibm903':
-                return 'IBM903';
-
-            case '904':
-            case 'cp904':
-            case 'csibbm904':
-            case 'ibm904':
-                return 'IBM904';
-
-            case 'cp905':
-            case 'csibm905':
-            case 'ebcdiccptr':
-            case 'ibm905':
-                return 'IBM905';
-
-            case 'cp918':
-            case 'csibm918':
-            case 'ebcdiccpar2':
-            case 'ibm918':
-                return 'IBM918';
-
-            case 'ccsid924':
-            case 'cp924':
-            case 'ebcdiclatin9euro':
-            case 'ibm924':
-                return 'IBM00924';
-
-            case 'cp1026':
-            case 'csibm1026':
-            case 'ibm1026':
-                return 'IBM1026';
-
-            case 'ibm1047':
-                return 'IBM1047';
-
-            case 'ccsid1140':
-            case 'cp1140':
-            case 'ebcdicus37euro':
-            case 'ibm1140':
-                return 'IBM01140';
-
-            case 'ccsid1141':
-            case 'cp1141':
-            case 'ebcdicde273euro':
-            case 'ibm1141':
-                return 'IBM01141';
-
-            case 'ccsid1142':
-            case 'cp1142':
-            case 'ebcdicdk277euro':
-            case 'ebcdicno277euro':
-            case 'ibm1142':
-                return 'IBM01142';
-
-            case 'ccsid1143':
-            case 'cp1143':
-            case 'ebcdicfi278euro':
-            case 'ebcdicse278euro':
-            case 'ibm1143':
-                return 'IBM01143';
-
-            case 'ccsid1144':
-            case 'cp1144':
-            case 'ebcdicit280euro':
-            case 'ibm1144':
-                return 'IBM01144';
-
-            case 'ccsid1145':
-            case 'cp1145':
-            case 'ebcdices284euro':
-            case 'ibm1145':
-                return 'IBM01145';
-
-            case 'ccsid1146':
-            case 'cp1146':
-            case 'ebcdicgb285euro':
-            case 'ibm1146':
-                return 'IBM01146';
-
-            case 'ccsid1147':
-            case 'cp1147':
-            case 'ebcdicfr297euro':
-            case 'ibm1147':
-                return 'IBM01147';
-
-            case 'ccsid1148':
-            case 'cp1148':
-            case 'ebcdicinternational500euro':
-            case 'ibm1148':
-                return 'IBM01148';
-
-            case 'ccsid1149':
-            case 'cp1149':
-            case 'ebcdicis871euro':
-            case 'ibm1149':
-                return 'IBM01149';
-
-            case 'csiso143iecp271':
-            case 'iecp271':
-            case 'isoir143':
-                return 'IEC_P27-1';
-
-            case 'csiso49inis':
-            case 'inis':
-            case 'isoir49':
-                return 'INIS';
-
-            case 'csiso50inis8':
-            case 'inis8':
-            case 'isoir50':
-                return 'INIS-8';
-
-            case 'csiso51iniscyrillic':
-            case 'iniscyrillic':
-            case 'isoir51':
-                return 'INIS-cyrillic';
-
-            case 'csinvariant':
-            case 'invariant':
-                return 'INVARIANT';
-
-            case 'iso2022cn':
-                return 'ISO-2022-CN';
-
-            case 'iso2022cnext':
-                return 'ISO-2022-CN-EXT';
-
-            case 'csiso2022jp':
-            case 'iso2022jp':
-                return 'ISO-2022-JP';
-
-            case 'csiso2022jp2':
-            case 'iso2022jp2':
-                return 'ISO-2022-JP-2';
-
-            case 'csiso2022kr':
-            case 'iso2022kr':
-                return 'ISO-2022-KR';
-
-            case 'cswindows30latin1':
-            case 'iso88591windows30latin1':
-                return 'ISO-8859-1-Windows-3.0-Latin-1';
-
-            case 'cswindows31latin1':
-            case 'iso88591windows31latin1':
-                return 'ISO-8859-1-Windows-3.1-Latin-1';
-
-            case 'csisolatin2':
-            case 'iso88592':
-            case 'iso885921987':
-            case 'isoir101':
-            case 'l2':
-            case 'latin2':
-                return 'ISO-8859-2';
-
-            case 'cswindows31latin2':
-            case 'iso88592windowslatin2':
-                return 'ISO-8859-2-Windows-Latin-2';
-
-            case 'csisolatin3':
-            case 'iso88593':
-            case 'iso885931988':
-            case 'isoir109':
-            case 'l3':
-            case 'latin3':
-                return 'ISO-8859-3';
-
-            case 'csisolatin4':
-            case 'iso88594':
-            case 'iso885941988':
-            case 'isoir110':
-            case 'l4':
-            case 'latin4':
-                return 'ISO-8859-4';
-
-            case 'csisolatincyrillic':
-            case 'cyrillic':
-            case 'iso88595':
-            case 'iso885951988':
-            case 'isoir144':
-                return 'ISO-8859-5';
-
-            case 'arabic':
-            case 'asmo708':
-            case 'csisolatinarabic':
-            case 'ecma114':
-            case 'iso88596':
-            case 'iso885961987':
-            case 'isoir127':
-                return 'ISO-8859-6';
-
-            case 'csiso88596e':
-            case 'iso88596e':
-                return 'ISO-8859-6-E';
-
-            case 'csiso88596i':
-            case 'iso88596i':
-                return 'ISO-8859-6-I';
-
-            case 'csisolatingreek':
-            case 'ecma118':
-            case 'elot928':
-            case 'greek':
-            case 'greek8':
-            case 'iso88597':
-            case 'iso885971987':
-            case 'isoir126':
-                return 'ISO-8859-7';
-
-            case 'csisolatinhebrew':
-            case 'hebrew':
-            case 'iso88598':
-            case 'iso885981988':
-            case 'isoir138':
-                return 'ISO-8859-8';
-
-            case 'csiso88598e':
-            case 'iso88598e':
-                return 'ISO-8859-8-E';
-
-            case 'csiso88598i':
-            case 'iso88598i':
-                return 'ISO-8859-8-I';
-
-            case 'cswindows31latin5':
-            case 'iso88599windowslatin5':
-                return 'ISO-8859-9-Windows-Latin-5';
-
-            case 'csisolatin6':
-            case 'iso885910':
-            case 'iso8859101992':
-            case 'isoir157':
-            case 'l6':
-            case 'latin6':
-                return 'ISO-8859-10';
-
-            case 'iso885913':
-                return 'ISO-8859-13';
-
-            case 'iso885914':
-            case 'iso8859141998':
-            case 'isoceltic':
-            case 'isoir199':
-            case 'l8':
-            case 'latin8':
-                return 'ISO-8859-14';
-
-            case 'iso885915':
-            case 'latin9':
-                return 'ISO-8859-15';
-
-            case 'iso885916':
-            case 'iso8859162001':
-            case 'isoir226':
-            case 'l10':
-            case 'latin10':
-                return 'ISO-8859-16';
-
-            case 'iso10646j1':
-                return 'ISO-10646-J-1';
-
-            case 'csunicode':
-            case 'iso10646ucs2':
-                return 'ISO-10646-UCS-2';
-
-            case 'csucs4':
-            case 'iso10646ucs4':
-                return 'ISO-10646-UCS-4';
-
-            case 'csunicodeascii':
-            case 'iso10646ucsbasic':
-                return 'ISO-10646-UCS-Basic';
-
-            case 'csunicodelatin1':
-            case 'iso10646':
-            case 'iso10646unicodelatin1':
-                return 'ISO-10646-Unicode-Latin1';
-
-            case 'csiso10646utf1':
-            case 'iso10646utf1':
-                return 'ISO-10646-UTF-1';
-
-            case 'csiso115481':
-            case 'iso115481':
-            case 'isotr115481':
-                return 'ISO-11548-1';
-
-            case 'csiso90':
-            case 'isoir90':
-                return 'iso-ir-90';
-
-            case 'csunicodeibm1261':
-            case 'isounicodeibm1261':
-                return 'ISO-Unicode-IBM-1261';
-
-            case 'csunicodeibm1264':
-            case 'isounicodeibm1264':
-                return 'ISO-Unicode-IBM-1264';
-
-            case 'csunicodeibm1265':
-            case 'isounicodeibm1265':
-                return 'ISO-Unicode-IBM-1265';
-
-            case 'csunicodeibm1268':
-            case 'isounicodeibm1268':
-                return 'ISO-Unicode-IBM-1268';
-
-            case 'csunicodeibm1276':
-            case 'isounicodeibm1276':
-                return 'ISO-Unicode-IBM-1276';
-
-            case 'csiso646basic1983':
-            case 'iso646basic1983':
-            case 'ref':
-                return 'ISO_646.basic:1983';
-
-            case 'csiso2intlrefversion':
-            case 'irv':
-            case 'iso646irv1983':
-            case 'isoir2':
-                return 'ISO_646.irv:1983';
-
-            case 'csiso2033':
-            case 'e13b':
-            case 'iso20331983':
-            case 'isoir98':
-                return 'ISO_2033-1983';
-
-            case 'csiso5427cyrillic':
-            case 'iso5427':
-            case 'isoir37':
-                return 'ISO_5427';
-
-            case 'iso5427cyrillic1981':
-            case 'iso54271981':
-            case 'isoir54':
-                return 'ISO_5427:1981';
-
-            case 'csiso5428greek':
-            case 'iso54281980':
-            case 'isoir55':
-                return 'ISO_5428:1980';
-
-            case 'csiso6937add':
-            case 'iso6937225':
-            case 'isoir152':
-                return 'ISO_6937-2-25';
-
-            case 'csisotextcomm':
-            case 'iso69372add':
-            case 'isoir142':
-                return 'ISO_6937-2-add';
-
-            case 'csiso8859supp':
-            case 'iso8859supp':
-            case 'isoir154':
-            case 'latin125':
-                return 'ISO_8859-supp';
-
-            case 'csiso10367box':
-            case 'iso10367box':
-            case 'isoir155':
-                return 'ISO_10367-box';
-
-            case 'csiso15italian':
-            case 'iso646it':
-            case 'isoir15':
-            case 'it':
-                return 'IT';
-
-            case 'csiso13jisc6220jp':
-            case 'isoir13':
-            case 'jisc62201969':
-            case 'jisc62201969jp':
-            case 'katakana':
-            case 'x2017':
-                return 'JIS_C6220-1969-jp';
-
-            case 'csiso14jisc6220ro':
-            case 'iso646jp':
-            case 'isoir14':
-            case 'jisc62201969ro':
-            case 'jp':
-                return 'JIS_C6220-1969-ro';
-
-            case 'csiso42jisc62261978':
-            case 'isoir42':
-            case 'jisc62261978':
-                return 'JIS_C6226-1978';
-
-            case 'csiso87jisx208':
-            case 'isoir87':
-            case 'jisc62261983':
-            case 'jisx2081983':
-            case 'x208':
-                return 'JIS_C6226-1983';
-
-            case 'csiso91jisc62291984a':
-            case 'isoir91':
-            case 'jisc62291984a':
-            case 'jpocra':
-                return 'JIS_C6229-1984-a';
-
-            case 'csiso92jisc62991984b':
-            case 'iso646jpocrb':
-            case 'isoir92':
-            case 'jisc62291984b':
-            case 'jpocrb':
-                return 'JIS_C6229-1984-b';
-
-            case 'csiso93jis62291984badd':
-            case 'isoir93':
-            case 'jisc62291984badd':
-            case 'jpocrbadd':
-                return 'JIS_C6229-1984-b-add';
-
-            case 'csiso94jis62291984hand':
-            case 'isoir94':
-            case 'jisc62291984hand':
-            case 'jpocrhand':
-                return 'JIS_C6229-1984-hand';
-
-            case 'csiso95jis62291984handadd':
-            case 'isoir95':
-            case 'jisc62291984handadd':
-            case 'jpocrhandadd':
-                return 'JIS_C6229-1984-hand-add';
-
-            case 'csiso96jisc62291984kana':
-            case 'isoir96':
-            case 'jisc62291984kana':
-                return 'JIS_C6229-1984-kana';
-
-            case 'csjisencoding':
-            case 'jisencoding':
-                return 'JIS_Encoding';
-
-            case 'cshalfwidthkatakana':
-            case 'jisx201':
-            case 'x201':
-                return 'JIS_X0201';
-
-            case 'csiso159jisx2121990':
-            case 'isoir159':
-            case 'jisx2121990':
-            case 'x212':
-                return 'JIS_X0212-1990';
-
-            case 'csiso141jusib1002':
-            case 'iso646yu':
-            case 'isoir141':
-            case 'js':
-            case 'jusib1002':
-            case 'yu':
-                return 'JUS_I.B1.002';
-
-            case 'csiso147macedonian':
-            case 'isoir147':
-            case 'jusib1003mac':
-            case 'macedonian':
-                return 'JUS_I.B1.003-mac';
-
-            case 'csiso146serbian':
-            case 'isoir146':
-            case 'jusib1003serb':
-            case 'serbian':
-                return 'JUS_I.B1.003-serb';
-
-            case 'koi7switched':
-                return 'KOI7-switched';
-
-            case 'cskoi8r':
-            case 'koi8r':
-                return 'KOI8-R';
-
-            case 'koi8u':
-                return 'KOI8-U';
-
-            case 'csksc5636':
-            case 'iso646kr':
-            case 'ksc5636':
-                return 'KSC5636';
-
-            case 'cskz1048':
-            case 'kz1048':
-            case 'rk1048':
-            case 'strk10482002':
-                return 'KZ-1048';
-
-            case 'csiso19latingreek':
-            case 'isoir19':
-            case 'latingreek':
-                return 'latin-greek';
-
-            case 'csiso27latingreek1':
-            case 'isoir27':
-            case 'latingreek1':
-                return 'Latin-greek-1';
-
-            case 'csiso158lap':
-            case 'isoir158':
-            case 'lap':
-            case 'latinlap':
-                return 'latin-lap';
-
-            case 'csmacintosh':
-            case 'mac':
-            case 'macintosh':
-                return 'macintosh';
-
-            case 'csmicrosoftpublishing':
-            case 'microsoftpublishing':
-                return 'Microsoft-Publishing';
-
-            case 'csmnem':
-            case 'mnem':
-                return 'MNEM';
-
-            case 'csmnemonic':
-            case 'mnemonic':
-                return 'MNEMONIC';
-
-            case 'csiso86hungarian':
-            case 'hu':
-            case 'iso646hu':
-            case 'isoir86':
-            case 'msz77953':
-                return 'MSZ_7795.3';
-
-            case 'csnatsdano':
-            case 'isoir91':
-            case 'natsdano':
-                return 'NATS-DANO';
-
-            case 'csnatsdanoadd':
-            case 'isoir92':
-            case 'natsdanoadd':
-                return 'NATS-DANO-ADD';
-
-            case 'csnatssefi':
-            case 'isoir81':
-            case 'natssefi':
-                return 'NATS-SEFI';
-
-            case 'csnatssefiadd':
-            case 'isoir82':
-            case 'natssefiadd':
-                return 'NATS-SEFI-ADD';
-
-            case 'csiso151cuba':
-            case 'cuba':
-            case 'iso646cu':
-            case 'isoir151':
-            case 'ncnc1081':
-                return 'NC_NC00-10:81';
-
-            case 'csiso69french':
-            case 'fr':
-            case 'iso646fr':
-            case 'isoir69':
-            case 'nfz62010':
-                return 'NF_Z_62-010';
-
-            case 'csiso25french':
-            case 'iso646fr1':
-            case 'isoir25':
-            case 'nfz620101973':
-                return 'NF_Z_62-010_(1973)';
-
-            case 'csiso60danishnorwegian':
-            case 'csiso60norwegian1':
-            case 'iso646no':
-            case 'isoir60':
-            case 'no':
-            case 'ns45511':
-                return 'NS_4551-1';
-
-            case 'csiso61norwegian2':
-            case 'iso646no2':
-            case 'isoir61':
-            case 'no2':
-            case 'ns45512':
-                return 'NS_4551-2';
-
-            case 'osdebcdicdf3irv':
-                return 'OSD_EBCDIC_DF03_IRV';
-
-            case 'osdebcdicdf41':
-                return 'OSD_EBCDIC_DF04_1';
-
-            case 'osdebcdicdf415':
-                return 'OSD_EBCDIC_DF04_15';
-
-            case 'cspc8danishnorwegian':
-            case 'pc8danishnorwegian':
-                return 'PC8-Danish-Norwegian';
-
-            case 'cspc8turkish':
-            case 'pc8turkish':
-                return 'PC8-Turkish';
-
-            case 'csiso16portuguese':
-            case 'iso646pt':
-            case 'isoir16':
-            case 'pt':
-                return 'PT';
-
-            case 'csiso84portuguese2':
-            case 'iso646pt2':
-            case 'isoir84':
-            case 'pt2':
-                return 'PT2';
-
-            case 'cp154':
-            case 'csptcp154':
-            case 'cyrillicasian':
-            case 'pt154':
-            case 'ptcp154':
-                return 'PTCP154';
-
-            case 'scsu':
-                return 'SCSU';
-
-            case 'csiso10swedish':
-            case 'fi':
-            case 'iso646fi':
-            case 'iso646se':
-            case 'isoir10':
-            case 'se':
-            case 'sen850200b':
-                return 'SEN_850200_B';
-
-            case 'csiso11swedishfornames':
-            case 'iso646se2':
-            case 'isoir11':
-            case 'se2':
-            case 'sen850200c':
-                return 'SEN_850200_C';
-
-            case 'csiso102t617bit':
-            case 'isoir102':
-            case 't617bit':
-                return 'T.61-7bit';
-
-            case 'csiso103t618bit':
-            case 'isoir103':
-            case 't61':
-            case 't618bit':
-                return 'T.61-8bit';
-
-            case 'csiso128t101g2':
-            case 'isoir128':
-            case 't101g2':
-                return 'T.101-G2';
-
-            case 'cstscii':
-            case 'tscii':
-                return 'TSCII';
-
-            case 'csunicode11':
-            case 'unicode11':
-                return 'UNICODE-1-1';
-
-            case 'csunicode11utf7':
-            case 'unicode11utf7':
-                return 'UNICODE-1-1-UTF-7';
-
-            case 'csunknown8bit':
-            case 'unknown8bit':
-                return 'UNKNOWN-8BIT';
-
-            case 'ansix341968':
-            case 'ansix341986':
-            case 'ascii':
-            case 'cp367':
-            case 'csascii':
-            case 'ibm367':
-            case 'iso646irv1991':
-            case 'iso646us':
-            case 'isoir6':
-            case 'us':
-            case 'usascii':
-                return 'US-ASCII';
-
-            case 'csusdk':
-            case 'usdk':
-                return 'us-dk';
-
-            case 'utf7':
-                return 'UTF-7';
-
-            case 'utf8':
-                return 'UTF-8';
-
-            case 'utf16':
-                return 'UTF-16';
-
-            case 'utf16be':
-                return 'UTF-16BE';
-
-            case 'utf16le':
-                return 'UTF-16LE';
-
-            case 'utf32':
-                return 'UTF-32';
-
-            case 'utf32be':
-                return 'UTF-32BE';
-
-            case 'utf32le':
-                return 'UTF-32LE';
-
-            case 'csventurainternational':
-            case 'venturainternational':
-                return 'Ventura-International';
-
-            case 'csventuramath':
-            case 'venturamath':
-                return 'Ventura-Math';
-
-            case 'csventuraus':
-            case 'venturaus':
-                return 'Ventura-US';
-
-            case 'csiso70videotexsupp1':
-            case 'isoir70':
-            case 'videotexsuppl':
-                return 'videotex-suppl';
-
-            case 'csviqr':
-            case 'viqr':
-                return 'VIQR';
-
-            case 'csviscii':
-            case 'viscii':
-                return 'VISCII';
-
-            case 'csshiftjis':
-            case 'cswindows31j':
-            case 'mskanji':
-            case 'shiftjis':
-            case 'windows31j':
-                return 'Windows-31J';
-
-            case 'iso885911':
-            case 'tis620':
-                return 'windows-874';
-
-            case 'cseuckr':
-            case 'csksc56011987':
-            case 'euckr':
-            case 'isoir149':
-            case 'korean':
-            case 'ksc5601':
-            case 'ksc56011987':
-            case 'ksc56011989':
-            case 'windows949':
-                return 'windows-949';
-
-            case 'windows1250':
-                return 'windows-1250';
-
-            case 'windows1251':
-                return 'windows-1251';
-
-            case 'cp819':
-            case 'csisolatin1':
-            case 'ibm819':
-            case 'iso88591':
-            case 'iso885911987':
-            case 'isoir100':
-            case 'l1':
-            case 'latin1':
-            case 'windows1252':
-                return 'windows-1252';
-
-            case 'windows1253':
-                return 'windows-1253';
-
-            case 'csisolatin5':
-            case 'iso88599':
-            case 'iso885991989':
-            case 'isoir148':
-            case 'l5':
-            case 'latin5':
-            case 'windows1254':
-                return 'windows-1254';
-
-            case 'windows1255':
-                return 'windows-1255';
-
-            case 'windows1256':
-                return 'windows-1256';
-
-            case 'windows1257':
-                return 'windows-1257';
-
-            case 'windows1258':
-                return 'windows-1258';
-
-            default:
-                return $charset;
-        }
-    }
-
-    public static function get_curl_version()
-    {
-        if (is_array($curl = curl_version())) {
-            $curl = $curl['version'];
-        } elseif (substr($curl, 0, 5) === 'curl/') {
-            $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
-        } elseif (substr($curl, 0, 8) === 'libcurl/') {
-            $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
-        } else {
-            $curl = 0;
-        }
-        return $curl;
-    }
-
-    /**
-     * Strip HTML comments
-     *
-     * @param string $data Data to strip comments from
-     * @return string Comment stripped string
-     */
-    public static function strip_comments($data)
-    {
-        $output = '';
-        while (($start = strpos($data, '<!--')) !== false) {
-            $output .= substr($data, 0, $start);
-            if (($end = strpos($data, '-->', $start)) !== false) {
-                $data = substr_replace($data, '', 0, $end + 3);
-            } else {
-                $data = '';
-            }
-        }
-        return $output . $data;
-    }
-
-    public static function parse_date($dt)
-    {
-        $parser = \SimplePie\Parse\Date::get();
-        return $parser->parse($dt);
-    }
-
-    /**
-     * Decode HTML entities
-     *
-     * @deprecated since SimplePie 1.3, use DOMDocument instead
-     * @param string $data Input data
-     * @return string Output data
-     */
-    public static function entities_decode($data)
-    {
-        // trigger_error(sprintf('Using method "' . __METHOD__ . '" is deprecated since SimplePie 1.3, use "DOMDocument" instead.'), \E_USER_DEPRECATED);
-
-        $decoder = new \SimplePie_Decode_HTML_Entities($data);
-        return $decoder->parse();
-    }
-
-    /**
-     * Remove RFC822 comments
-     *
-     * @param string $data Data to strip comments from
-     * @return string Comment stripped string
-     */
-    public static function uncomment_rfc822($string)
-    {
-        $string = (string) $string;
-        $position = 0;
-        $length = strlen($string);
-        $depth = 0;
-
-        $output = '';
-
-        while ($position < $length && ($pos = strpos($string, '(', $position)) !== false) {
-            $output .= substr($string, $position, $pos - $position);
-            $position = $pos + 1;
-            if ($string[$pos - 1] !== '\\') {
-                $depth++;
-                while ($depth && $position < $length) {
-                    $position += strcspn($string, '()', $position);
-                    if ($string[$position - 1] === '\\') {
-                        $position++;
-                        continue;
-                    } elseif (isset($string[$position])) {
-                        switch ($string[$position]) {
-                            case '(':
-                                $depth++;
-                                break;
-
-                            case ')':
-                                $depth--;
-                                break;
-                        }
-                        $position++;
-                    } else {
-                        break;
-                    }
-                }
-            } else {
-                $output .= '(';
-            }
-        }
-        $output .= substr($string, $position);
-
-        return $output;
-    }
-
-    public static function parse_mime($mime)
-    {
-        if (($pos = strpos($mime, ';')) === false) {
-            return trim($mime);
-        }
-
-        return trim(substr($mime, 0, $pos));
-    }
-
-    public static function atom_03_construct_type($attribs)
-    {
-        if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode'])) === 'base64') {
-            $mode = \SimplePie\SimplePie::CONSTRUCT_BASE64;
-        } else {
-            $mode = \SimplePie\SimplePie::CONSTRUCT_NONE;
-        }
-        if (isset($attribs['']['type'])) {
-            switch (strtolower(trim($attribs['']['type']))) {
-                case 'text':
-                case 'text/plain':
-                    return \SimplePie\SimplePie::CONSTRUCT_TEXT | $mode;
-
-                case 'html':
-                case 'text/html':
-                    return \SimplePie\SimplePie::CONSTRUCT_HTML | $mode;
-
-                case 'xhtml':
-                case 'application/xhtml+xml':
-                    return \SimplePie\SimplePie::CONSTRUCT_XHTML | $mode;
-
-                default:
-                    return \SimplePie\SimplePie::CONSTRUCT_NONE | $mode;
-            }
-        }
-
-        return \SimplePie\SimplePie::CONSTRUCT_TEXT | $mode;
-    }
-
-    public static function atom_10_construct_type($attribs)
-    {
-        if (isset($attribs['']['type'])) {
-            switch (strtolower(trim($attribs['']['type']))) {
-                case 'text':
-                    return \SimplePie\SimplePie::CONSTRUCT_TEXT;
-
-                case 'html':
-                    return \SimplePie\SimplePie::CONSTRUCT_HTML;
-
-                case 'xhtml':
-                    return \SimplePie\SimplePie::CONSTRUCT_XHTML;
-
-                default:
-                    return \SimplePie\SimplePie::CONSTRUCT_NONE;
-            }
-        }
-        return \SimplePie\SimplePie::CONSTRUCT_TEXT;
-    }
-
-    public static function atom_10_content_construct_type($attribs)
-    {
-        if (isset($attribs['']['type'])) {
-            $type = strtolower(trim($attribs['']['type']));
-            switch ($type) {
-                case 'text':
-                    return \SimplePie\SimplePie::CONSTRUCT_TEXT;
-
-                case 'html':
-                    return \SimplePie\SimplePie::CONSTRUCT_HTML;
-
-                case 'xhtml':
-                    return \SimplePie\SimplePie::CONSTRUCT_XHTML;
-            }
-            if (in_array(substr($type, -4), ['+xml', '/xml']) || substr($type, 0, 5) === 'text/') {
-                return \SimplePie\SimplePie::CONSTRUCT_NONE;
-            } else {
-                return \SimplePie\SimplePie::CONSTRUCT_BASE64;
-            }
-        }
-
-        return \SimplePie\SimplePie::CONSTRUCT_TEXT;
-    }
-
-    public static function is_isegment_nz_nc($string)
-    {
-        return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string);
-    }
-
-    public static function space_separated_tokens($string)
-    {
-        $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
-        $string_length = strlen($string);
-
-        $position = strspn($string, $space_characters);
-        $tokens = [];
-
-        while ($position < $string_length) {
-            $len = strcspn($string, $space_characters, $position);
-            $tokens[] = substr($string, $position, $len);
-            $position += $len;
-            $position += strspn($string, $space_characters, $position);
-        }
-
-        return $tokens;
-    }
-
-    /**
-     * Converts a unicode codepoint to a UTF-8 character
-     *
-     * @static
-     * @param int $codepoint Unicode codepoint
-     * @return string UTF-8 character
-     */
-    public static function codepoint_to_utf8($codepoint)
-    {
-        $codepoint = (int) $codepoint;
-        if ($codepoint < 0) {
-            return false;
-        } elseif ($codepoint <= 0x7f) {
-            return chr($codepoint);
-        } elseif ($codepoint <= 0x7ff) {
-            return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
-        } elseif ($codepoint <= 0xffff) {
-            return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
-        } elseif ($codepoint <= 0x10ffff) {
-            return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
-        }
-
-        // U+FFFD REPLACEMENT CHARACTER
-        return "\xEF\xBF\xBD";
-    }
-
-    /**
-     * Similar to parse_str()
-     *
-     * Returns an associative array of name/value pairs, where the value is an
-     * array of values that have used the same name
-     *
-     * @static
-     * @param string $str The input string.
-     * @return array
-     */
-    public static function parse_str($str)
-    {
-        $return = [];
-        $str = explode('&', $str);
-
-        foreach ($str as $section) {
-            if (strpos($section, '=') !== false) {
-                [$name, $value] = explode('=', $section, 2);
-                $return[urldecode($name)][] = urldecode($value);
-            } else {
-                $return[urldecode($section)][] = null;
-            }
-        }
-
-        return $return;
-    }
-
-    /**
-     * Detect XML encoding, as per XML 1.0 Appendix F.1
-     *
-     * @todo Add support for EBCDIC
-     * @param string $data XML data
-     * @param \SimplePie\Registry $registry Class registry
-     * @return array Possible encodings
-     */
-    public static function xml_encoding($data, $registry)
-    {
-        // UTF-32 Big Endian BOM
-        if (substr($data, 0, 4) === "\x00\x00\xFE\xFF") {
-            $encoding[] = 'UTF-32BE';
-        }
-        // UTF-32 Little Endian BOM
-        elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00") {
-            $encoding[] = 'UTF-32LE';
-        }
-        // UTF-16 Big Endian BOM
-        elseif (substr($data, 0, 2) === "\xFE\xFF") {
-            $encoding[] = 'UTF-16BE';
-        }
-        // UTF-16 Little Endian BOM
-        elseif (substr($data, 0, 2) === "\xFF\xFE") {
-            $encoding[] = 'UTF-16LE';
-        }
-        // UTF-8 BOM
-        elseif (substr($data, 0, 3) === "\xEF\xBB\xBF") {
-            $encoding[] = 'UTF-8';
-        }
-        // UTF-32 Big Endian Without BOM
-        elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C") {
-            if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E")) {
-                $parser = $registry->create(Parser::class, [Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8')]);
-                if ($parser->parse()) {
-                    $encoding[] = $parser->encoding;
-                }
-            }
-            $encoding[] = 'UTF-32BE';
-        }
-        // UTF-32 Little Endian Without BOM
-        elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00") {
-            if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00")) {
-                $parser = $registry->create(Parser::class, [Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8')]);
-                if ($parser->parse()) {
-                    $encoding[] = $parser->encoding;
-                }
-            }
-            $encoding[] = 'UTF-32LE';
-        }
-        // UTF-16 Big Endian Without BOM
-        elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C") {
-            if ($pos = strpos($data, "\x00\x3F\x00\x3E")) {
-                $parser = $registry->create(Parser::class, [Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8')]);
-                if ($parser->parse()) {
-                    $encoding[] = $parser->encoding;
-                }
-            }
-            $encoding[] = 'UTF-16BE';
-        }
-        // UTF-16 Little Endian Without BOM
-        elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00") {
-            if ($pos = strpos($data, "\x3F\x00\x3E\x00")) {
-                $parser = $registry->create(Parser::class, [Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8')]);
-                if ($parser->parse()) {
-                    $encoding[] = $parser->encoding;
-                }
-            }
-            $encoding[] = 'UTF-16LE';
-        }
-        // US-ASCII (or superset)
-        elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C") {
-            if ($pos = strpos($data, "\x3F\x3E")) {
-                $parser = $registry->create(Parser::class, [substr($data, 5, $pos - 5)]);
-                if ($parser->parse()) {
-                    $encoding[] = $parser->encoding;
-                }
-            }
-            $encoding[] = 'UTF-8';
-        }
-        // Fallback to UTF-8
-        else {
-            $encoding[] = 'UTF-8';
-        }
-        return $encoding;
-    }
-
-    public static function output_javascript()
-    {
-        if (function_exists('ob_gzhandler')) {
-            ob_start('ob_gzhandler');
-        }
-        header('Content-type: text/javascript; charset: UTF-8');
-        header('Cache-Control: must-revalidate');
-        header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
-
-        $body = <<<END
-function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
-	if (placeholder != '') {
-		document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
-	}
-	else {
-		document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
-	}
-}
-
-function embed_flash(bgcolor, width, height, link, loop, type) {
-	document.writeln('<embed src="'+link+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="'+type+'" quality="high" width="'+width+'" height="'+height+'" bgcolor="'+bgcolor+'" loop="'+loop+'"></embed>');
-}
-
-function embed_flv(width, height, link, placeholder, loop, player) {
-	document.writeln('<embed src="'+player+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="'+width+'" height="'+height+'" wmode="transparent" flashvars="file='+link+'&autostart=false&repeat='+loop+'&showdigits=true&showfsbutton=false"></embed>');
-}
-
-function embed_wmedia(width, height, link) {
-	document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
-}
-END;
-        echo $body;
-    }
-
-    /**
-     * Get the SimplePie build timestamp
-     *
-     * Uses the git index if it exists, otherwise uses the modification time
-     * of the newest file.
-     */
-    public static function get_build()
-    {
-        if (static::$SIMPLEPIE_BUILD !== null) {
-            return static::$SIMPLEPIE_BUILD;
-        }
-
-        $root = dirname(__FILE__, 2);
-        if (file_exists($root . '/.git/index')) {
-            static::$SIMPLEPIE_BUILD = filemtime($root . '/.git/index');
-
-            return static::$SIMPLEPIE_BUILD;
-        } elseif (file_exists($root . '/SimplePie')) {
-            $time = 0;
-            foreach (glob($root . '/SimplePie/*.php') as $file) {
-                if (($mtime = filemtime($file)) > $time) {
-                    $time = $mtime;
-                }
-            }
-            static::$SIMPLEPIE_BUILD = $time;
-
-            return static::$SIMPLEPIE_BUILD;
-        } elseif (file_exists(dirname(__FILE__) . '/Core.php')) {
-            static::$SIMPLEPIE_BUILD = filemtime(dirname(__FILE__) . '/Core.php');
-
-            return static::$SIMPLEPIE_BUILD;
-        }
-
-        static::$SIMPLEPIE_BUILD = filemtime(__FILE__);
-
-        return static::$SIMPLEPIE_BUILD;
-    }
-
-    /**
-     * Get the default user agent string
-     *
-     * @return string
-     */
-    public static function get_default_useragent()
-    {
-        return \SimplePie\SimplePie::NAME . '/' . \SimplePie\SimplePie::VERSION . ' (Feed Parser; ' . \SimplePie\SimplePie::URL . '; Allow like Gecko) Build/' . static::get_build();
-    }
-
-    /**
-     * Format debugging information
-     */
-    public static function debug(&$sp)
-    {
-        $info = 'SimplePie ' . \SimplePie\SimplePie::VERSION . ' Build ' . static::get_build() . "\n";
-        $info .= 'PHP ' . PHP_VERSION . "\n";
-        if ($sp->error() !== null) {
-            $info .= 'Error occurred: ' . $sp->error() . "\n";
-        } else {
-            $info .= "No error found.\n";
-        }
-        $info .= "Extensions:\n";
-        $extensions = ['pcre', 'curl', 'zlib', 'mbstring', 'iconv', 'xmlreader', 'xml'];
-        foreach ($extensions as $ext) {
-            if (extension_loaded($ext)) {
-                $info .= "    $ext loaded\n";
-                switch ($ext) {
-                    case 'pcre':
-                        $info .= '      Version ' . PCRE_VERSION . "\n";
-                        break;
-                    case 'curl':
-                        $version = curl_version();
-                        $info .= '      Version ' . $version['version'] . "\n";
-                        break;
-                    case 'mbstring':
-                        $info .= '      Overloading: ' . mb_get_info('func_overload') . "\n";
-                        break;
-                    case 'iconv':
-                        $info .= '      Version ' . ICONV_VERSION . "\n";
-                        break;
-                    case 'xml':
-                        $info .= '      Version ' . LIBXML_DOTTED_VERSION . "\n";
-                        break;
-                }
-            } else {
-                $info .= "    $ext not loaded\n";
-            }
-        }
-        return $info;
-    }
-
-    public static function silence_errors($num, $str)
-    {
-        // No-op
-    }
-
-    /**
-     * Sanitize a URL by removing HTTP credentials.
-     * @param string $url the URL to sanitize.
-     * @return string the same URL without HTTP credentials.
-     */
-    public static function url_remove_credentials($url)
-    {
-        return preg_replace('#^(https?://)[^/:@]+:[^/:@]+@#i', '$1', $url);
-    }
-}
-
-class_alias('SimplePie\Misc', 'SimplePie_Misc', false);
-
-}
-
-namespace SimplePie\Net {
-
-/**
- * Class to validate and to work with IPv6 addresses.
- *
- * @package SimplePie
- * @subpackage HTTP
- * @copyright 2003-2005 The PHP Group
- * @license http://www.opensource.org/licenses/bsd-license.php
- * @link http://pear.php.net/package/Net_IPv6
- * @author Alexander Merz <alexander.merz@web.de>
- * @author elfrink at introweb dot nl
- * @author Josh Peck <jmp at joshpeck dot org>
- * @author Sam Sneddon <geoffers@gmail.com>
- */
-class IPv6
-{
-    /**
-     * Uncompresses an IPv6 address
-     *
-     * RFC 4291 allows you to compress concecutive zero pieces in an address to
-     * '::'. This method expects a valid IPv6 address and expands the '::' to
-     * the required number of zero pieces.
-     *
-     * Example:  FF01::101   ->  FF01:0:0:0:0:0:0:101
-     *           ::1         ->  0:0:0:0:0:0:0:1
-     *
-     * @author Alexander Merz <alexander.merz@web.de>
-     * @author elfrink at introweb dot nl
-     * @author Josh Peck <jmp at joshpeck dot org>
-     * @copyright 2003-2005 The PHP Group
-     * @license http://www.opensource.org/licenses/bsd-license.php
-     * @param string $ip An IPv6 address
-     * @return string The uncompressed IPv6 address
-     */
-    public static function uncompress($ip)
-    {
-        $c1 = -1;
-        $c2 = -1;
-        if (substr_count($ip, '::') === 1) {
-            [$ip1, $ip2] = explode('::', $ip);
-            if ($ip1 === '') {
-                $c1 = -1;
-            } else {
-                $c1 = substr_count($ip1, ':');
-            }
-            if ($ip2 === '') {
-                $c2 = -1;
-            } else {
-                $c2 = substr_count($ip2, ':');
-            }
-            if (strpos($ip2, '.') !== false) {
-                $c2++;
-            }
-            // ::
-            if ($c1 === -1 && $c2 === -1) {
-                $ip = '0:0:0:0:0:0:0:0';
-            }
-            // ::xxx
-            elseif ($c1 === -1) {
-                $fill = str_repeat('0:', 7 - $c2);
-                $ip = str_replace('::', $fill, $ip);
-            }
-            // xxx::
-            elseif ($c2 === -1) {
-                $fill = str_repeat(':0', 7 - $c1);
-                $ip = str_replace('::', $fill, $ip);
-            }
-            // xxx::xxx
-            else {
-                $fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
-                $ip = str_replace('::', $fill, $ip);
-            }
-        }
-        return $ip;
-    }
-
-    /**
-     * Compresses an IPv6 address
-     *
-     * RFC 4291 allows you to compress concecutive zero pieces in an address to
-     * '::'. This method expects a valid IPv6 address and compresses consecutive
-     * zero pieces to '::'.
-     *
-     * Example:  FF01:0:0:0:0:0:0:101   ->  FF01::101
-     *           0:0:0:0:0:0:0:1        ->  ::1
-     *
-     * @see uncompress()
-     * @param string $ip An IPv6 address
-     * @return string The compressed IPv6 address
-     */
-    public static function compress($ip)
-    {
-        // Prepare the IP to be compressed
-        $ip = self::uncompress($ip);
-        $ip_parts = self::split_v6_v4($ip);
-
-        // Replace all leading zeros
-        $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
-
-        // Find bunches of zeros
-        if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE)) {
-            $max = 0;
-            $pos = null;
-            foreach ($matches[0] as $match) {
-                if (strlen($match[0]) > $max) {
-                    $max = strlen($match[0]);
-                    $pos = $match[1];
-                }
-            }
-
-            $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
-        }
-
-        if ($ip_parts[1] !== '') {
-            return implode(':', $ip_parts);
-        }
-
-        return $ip_parts[0];
-    }
-
-    /**
-     * Splits an IPv6 address into the IPv6 and IPv4 representation parts
-     *
-     * RFC 4291 allows you to represent the last two parts of an IPv6 address
-     * using the standard IPv4 representation
-     *
-     * Example:  0:0:0:0:0:0:13.1.68.3
-     *           0:0:0:0:0:FFFF:129.144.52.38
-     *
-     * @param string $ip An IPv6 address
-     * @return array [0] contains the IPv6 represented part, and [1] the IPv4 represented part
-     */
-    private static function split_v6_v4($ip)
-    {
-        if (strpos($ip, '.') !== false) {
-            $pos = strrpos($ip, ':');
-            $ipv6_part = substr($ip, 0, $pos);
-            $ipv4_part = substr($ip, $pos + 1);
-            return [$ipv6_part, $ipv4_part];
-        }
-
-        return [$ip, ''];
-    }
-
-    /**
-     * Checks an IPv6 address
-     *
-     * Checks if the given IP is a valid IPv6 address
-     *
-     * @param string $ip An IPv6 address
-     * @return bool true if $ip is a valid IPv6 address
-     */
-    public static function check_ipv6($ip)
-    {
-        $ip = self::uncompress($ip);
-        [$ipv6, $ipv4] = self::split_v6_v4($ip);
-        $ipv6 = explode(':', $ipv6);
-        $ipv4 = explode('.', $ipv4);
-        if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4) {
-            foreach ($ipv6 as $ipv6_part) {
-                // The section can't be empty
-                if ($ipv6_part === '') {
-                    return false;
-                }
-
-                // Nor can it be over four characters
-                if (strlen($ipv6_part) > 4) {
-                    return false;
-                }
-
-                // Remove leading zeros (this is safe because of the above)
-                $ipv6_part = ltrim($ipv6_part, '0');
-                if ($ipv6_part === '') {
-                    $ipv6_part = '0';
-                }
-
-                // Check the value is valid
-                $value = hexdec($ipv6_part);
-                if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF) {
-                    return false;
-                }
-            }
-            if (count($ipv4) === 4) {
-                foreach ($ipv4 as $ipv4_part) {
-                    $value = (int) $ipv4_part;
-                    if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF) {
-                        return false;
-                    }
-                }
-            }
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Checks if the given IP is a valid IPv6 address
-     *
-     * @codeCoverageIgnore
-     * @deprecated Use {@see IPv6::check_ipv6()} instead
-     * @see check_ipv6
-     * @param string $ip An IPv6 address
-     * @return bool true if $ip is a valid IPv6 address
-     */
-    public static function checkIPv6($ip)
-    {
-        return self::check_ipv6($ip);
-    }
-}
-
-class_alias('SimplePie\Net\IPv6', 'SimplePie_Net_IPv6');
-
-}
-
-namespace SimplePie\Parse {
-
-/**
- * Date Parser
- *
- * @package SimplePie
- * @subpackage Parsing
- */
-class Date
-{
-    /**
-     * Input data
-     *
-     * @access protected
-     * @var string
-     */
-    public $date;
-
-    /**
-     * List of days, calendar day name => ordinal day number in the week
-     *
-     * @access protected
-     * @var array
-     */
-    public $day = [
-        // English
-        'mon' => 1,
-        'monday' => 1,
-        'tue' => 2,
-        'tuesday' => 2,
-        'wed' => 3,
-        'wednesday' => 3,
-        'thu' => 4,
-        'thursday' => 4,
-        'fri' => 5,
-        'friday' => 5,
-        'sat' => 6,
-        'saturday' => 6,
-        'sun' => 7,
-        'sunday' => 7,
-        // Dutch
-        'maandag' => 1,
-        'dinsdag' => 2,
-        'woensdag' => 3,
-        'donderdag' => 4,
-        'vrijdag' => 5,
-        'zaterdag' => 6,
-        'zondag' => 7,
-        // French
-        'lundi' => 1,
-        'mardi' => 2,
-        'mercredi' => 3,
-        'jeudi' => 4,
-        'vendredi' => 5,
-        'samedi' => 6,
-        'dimanche' => 7,
-        // German
-        'montag' => 1,
-        'mo' => 1,
-        'dienstag' => 2,
-        'di' => 2,
-        'mittwoch' => 3,
-        'mi' => 3,
-        'donnerstag' => 4,
-        'do' => 4,
-        'freitag' => 5,
-        'fr' => 5,
-        'samstag' => 6,
-        'sa' => 6,
-        'sonnabend' => 6,
-        // AFAIK no short form for sonnabend
-        'so' => 7,
-        'sonntag' => 7,
-        // Italian
-        'lunedì' => 1,
-        'martedì' => 2,
-        'mercoledì' => 3,
-        'giovedì' => 4,
-        'venerdì' => 5,
-        'sabato' => 6,
-        'domenica' => 7,
-        // Spanish
-        'lunes' => 1,
-        'martes' => 2,
-        'miércoles' => 3,
-        'jueves' => 4,
-        'viernes' => 5,
-        'sábado' => 6,
-        'domingo' => 7,
-        // Finnish
-        'maanantai' => 1,
-        'tiistai' => 2,
-        'keskiviikko' => 3,
-        'torstai' => 4,
-        'perjantai' => 5,
-        'lauantai' => 6,
-        'sunnuntai' => 7,
-        // Hungarian
-        'hétfő' => 1,
-        'kedd' => 2,
-        'szerda' => 3,
-        'csütörtok' => 4,
-        'péntek' => 5,
-        'szombat' => 6,
-        'vasárnap' => 7,
-        // Greek
-        'Δευ' => 1,
-        'Τρι' => 2,
-        'Τετ' => 3,
-        'Πεμ' => 4,
-        'Παρ' => 5,
-        'Σαβ' => 6,
-        'Κυρ' => 7,
-        // Russian
-        'Пн.' => 1,
-        'Ð’Ñ‚.' => 2,
-        'Ср.' => 3,
-        'Чт.' => 4,
-        'Пт.' => 5,
-        'Сб.' => 6,
-        'Вс.' => 7,
-    ];
-
-    /**
-     * List of months, calendar month name => calendar month number
-     *
-     * @access protected
-     * @var array
-     */
-    public $month = [
-        // English
-        'jan' => 1,
-        'january' => 1,
-        'feb' => 2,
-        'february' => 2,
-        'mar' => 3,
-        'march' => 3,
-        'apr' => 4,
-        'april' => 4,
-        'may' => 5,
-        // No long form of May
-        'jun' => 6,
-        'june' => 6,
-        'jul' => 7,
-        'july' => 7,
-        'aug' => 8,
-        'august' => 8,
-        'sep' => 9,
-        'september' => 9,
-        'oct' => 10,
-        'october' => 10,
-        'nov' => 11,
-        'november' => 11,
-        'dec' => 12,
-        'december' => 12,
-        // Dutch
-        'januari' => 1,
-        'februari' => 2,
-        'maart' => 3,
-        'april' => 4,
-        'mei' => 5,
-        'juni' => 6,
-        'juli' => 7,
-        'augustus' => 8,
-        'september' => 9,
-        'oktober' => 10,
-        'november' => 11,
-        'december' => 12,
-        // French
-        'janvier' => 1,
-        'février' => 2,
-        'mars' => 3,
-        'avril' => 4,
-        'mai' => 5,
-        'juin' => 6,
-        'juillet' => 7,
-        'août' => 8,
-        'septembre' => 9,
-        'octobre' => 10,
-        'novembre' => 11,
-        'décembre' => 12,
-        // German
-        'januar' => 1,
-        'jan' => 1,
-        'februar' => 2,
-        'feb' => 2,
-        'märz' => 3,
-        'mär' => 3,
-        'april' => 4,
-        'apr' => 4,
-        'mai' => 5, // no short form for may
-        'juni' => 6,
-        'jun' => 6,
-        'juli' => 7,
-        'jul' => 7,
-        'august' => 8,
-        'aug' => 8,
-        'september' => 9,
-        'sep' => 9,
-        'oktober' => 10,
-        'okt' => 10,
-        'november' => 11,
-        'nov' => 11,
-        'dezember' => 12,
-        'dez' => 12,
-        // Italian
-        'gennaio' => 1,
-        'febbraio' => 2,
-        'marzo' => 3,
-        'aprile' => 4,
-        'maggio' => 5,
-        'giugno' => 6,
-        'luglio' => 7,
-        'agosto' => 8,
-        'settembre' => 9,
-        'ottobre' => 10,
-        'novembre' => 11,
-        'dicembre' => 12,
-        // Spanish
-        'enero' => 1,
-        'febrero' => 2,
-        'marzo' => 3,
-        'abril' => 4,
-        'mayo' => 5,
-        'junio' => 6,
-        'julio' => 7,
-        'agosto' => 8,
-        'septiembre' => 9,
-        'setiembre' => 9,
-        'octubre' => 10,
-        'noviembre' => 11,
-        'diciembre' => 12,
-        // Finnish
-        'tammikuu' => 1,
-        'helmikuu' => 2,
-        'maaliskuu' => 3,
-        'huhtikuu' => 4,
-        'toukokuu' => 5,
-        'kesäkuu' => 6,
-        'heinäkuu' => 7,
-        'elokuu' => 8,
-        'suuskuu' => 9,
-        'lokakuu' => 10,
-        'marras' => 11,
-        'joulukuu' => 12,
-        // Hungarian
-        'január' => 1,
-        'február' => 2,
-        'március' => 3,
-        'április' => 4,
-        'május' => 5,
-        'június' => 6,
-        'július' => 7,
-        'augusztus' => 8,
-        'szeptember' => 9,
-        'október' => 10,
-        'november' => 11,
-        'december' => 12,
-        // Greek
-        'Ιαν' => 1,
-        'Φεβ' => 2,
-        'Μάώ' => 3,
-        'Μαώ' => 3,
-        'Απρ' => 4,
-        'Μάι' => 5,
-        'Μαϊ' => 5,
-        'Μαι' => 5,
-        'Ιούν' => 6,
-        'Ιον' => 6,
-        'Ιούλ' => 7,
-        'Ιολ' => 7,
-        'Αύγ' => 8,
-        'Αυγ' => 8,
-        'Σεπ' => 9,
-        'Οκτ' => 10,
-        'Νοέ' => 11,
-        'Δεκ' => 12,
-        // Russian
-        'Янв' => 1,
-        'января' => 1,
-        'Фев' => 2,
-        'февраля' => 2,
-        'Мар' => 3,
-        'марта' => 3,
-        'Апр' => 4,
-        'апреля' => 4,
-        'Май' => 5,
-        'мая' => 5,
-        'Июн' => 6,
-        'июня' => 6,
-        'Июл' => 7,
-        'июля' => 7,
-        'Авг' => 8,
-        'августа' => 8,
-        'Сен' => 9,
-        'сентября' => 9,
-        'Окт' => 10,
-        'октября' => 10,
-        'Ноя' => 11,
-        'ноября' => 11,
-        'Дек' => 12,
-        'декабря' => 12,
-
-    ];
-
-    /**
-     * List of timezones, abbreviation => offset from UTC
-     *
-     * @access protected
-     * @var array
-     */
-    public $timezone = [
-        'ACDT' => 37800,
-        'ACIT' => 28800,
-        'ACST' => 34200,
-        'ACT' => -18000,
-        'ACWDT' => 35100,
-        'ACWST' => 31500,
-        'AEDT' => 39600,
-        'AEST' => 36000,
-        'AFT' => 16200,
-        'AKDT' => -28800,
-        'AKST' => -32400,
-        'AMDT' => 18000,
-        'AMT' => -14400,
-        'ANAST' => 46800,
-        'ANAT' => 43200,
-        'ART' => -10800,
-        'AZOST' => -3600,
-        'AZST' => 18000,
-        'AZT' => 14400,
-        'BIOT' => 21600,
-        'BIT' => -43200,
-        'BOT' => -14400,
-        'BRST' => -7200,
-        'BRT' => -10800,
-        'BST' => 3600,
-        'BTT' => 21600,
-        'CAST' => 18000,
-        'CAT' => 7200,
-        'CCT' => 23400,
-        'CDT' => -18000,
-        'CEDT' => 7200,
-        'CEST' => 7200,
-        'CET' => 3600,
-        'CGST' => -7200,
-        'CGT' => -10800,
-        'CHADT' => 49500,
-        'CHAST' => 45900,
-        'CIST' => -28800,
-        'CKT' => -36000,
-        'CLDT' => -10800,
-        'CLST' => -14400,
-        'COT' => -18000,
-        'CST' => -21600,
-        'CVT' => -3600,
-        'CXT' => 25200,
-        'DAVT' => 25200,
-        'DTAT' => 36000,
-        'EADT' => -18000,
-        'EAST' => -21600,
-        'EAT' => 10800,
-        'ECT' => -18000,
-        'EDT' => -14400,
-        'EEST' => 10800,
-        'EET' => 7200,
-        'EGT' => -3600,
-        'EKST' => 21600,
-        'EST' => -18000,
-        'FJT' => 43200,
-        'FKDT' => -10800,
-        'FKST' => -14400,
-        'FNT' => -7200,
-        'GALT' => -21600,
-        'GEDT' => 14400,
-        'GEST' => 10800,
-        'GFT' => -10800,
-        'GILT' => 43200,
-        'GIT' => -32400,
-        'GST' => 14400,
-        'GST' => -7200,
-        'GYT' => -14400,
-        'HAA' => -10800,
-        'HAC' => -18000,
-        'HADT' => -32400,
-        'HAE' => -14400,
-        'HAP' => -25200,
-        'HAR' => -21600,
-        'HAST' => -36000,
-        'HAT' => -9000,
-        'HAY' => -28800,
-        'HKST' => 28800,
-        'HMT' => 18000,
-        'HNA' => -14400,
-        'HNC' => -21600,
-        'HNE' => -18000,
-        'HNP' => -28800,
-        'HNR' => -25200,
-        'HNT' => -12600,
-        'HNY' => -32400,
-        'IRDT' => 16200,
-        'IRKST' => 32400,
-        'IRKT' => 28800,
-        'IRST' => 12600,
-        'JFDT' => -10800,
-        'JFST' => -14400,
-        'JST' => 32400,
-        'KGST' => 21600,
-        'KGT' => 18000,
-        'KOST' => 39600,
-        'KOVST' => 28800,
-        'KOVT' => 25200,
-        'KRAST' => 28800,
-        'KRAT' => 25200,
-        'KST' => 32400,
-        'LHDT' => 39600,
-        'LHST' => 37800,
-        'LINT' => 50400,
-        'LKT' => 21600,
-        'MAGST' => 43200,
-        'MAGT' => 39600,
-        'MAWT' => 21600,
-        'MDT' => -21600,
-        'MESZ' => 7200,
-        'MEZ' => 3600,
-        'MHT' => 43200,
-        'MIT' => -34200,
-        'MNST' => 32400,
-        'MSDT' => 14400,
-        'MSST' => 10800,
-        'MST' => -25200,
-        'MUT' => 14400,
-        'MVT' => 18000,
-        'MYT' => 28800,
-        'NCT' => 39600,
-        'NDT' => -9000,
-        'NFT' => 41400,
-        'NMIT' => 36000,
-        'NOVST' => 25200,
-        'NOVT' => 21600,
-        'NPT' => 20700,
-        'NRT' => 43200,
-        'NST' => -12600,
-        'NUT' => -39600,
-        'NZDT' => 46800,
-        'NZST' => 43200,
-        'OMSST' => 25200,
-        'OMST' => 21600,
-        'PDT' => -25200,
-        'PET' => -18000,
-        'PETST' => 46800,
-        'PETT' => 43200,
-        'PGT' => 36000,
-        'PHOT' => 46800,
-        'PHT' => 28800,
-        'PKT' => 18000,
-        'PMDT' => -7200,
-        'PMST' => -10800,
-        'PONT' => 39600,
-        'PST' => -28800,
-        'PWT' => 32400,
-        'PYST' => -10800,
-        'PYT' => -14400,
-        'RET' => 14400,
-        'ROTT' => -10800,
-        'SAMST' => 18000,
-        'SAMT' => 14400,
-        'SAST' => 7200,
-        'SBT' => 39600,
-        'SCDT' => 46800,
-        'SCST' => 43200,
-        'SCT' => 14400,
-        'SEST' => 3600,
-        'SGT' => 28800,
-        'SIT' => 28800,
-        'SRT' => -10800,
-        'SST' => -39600,
-        'SYST' => 10800,
-        'SYT' => 7200,
-        'TFT' => 18000,
-        'THAT' => -36000,
-        'TJT' => 18000,
-        'TKT' => -36000,
-        'TMT' => 18000,
-        'TOT' => 46800,
-        'TPT' => 32400,
-        'TRUT' => 36000,
-        'TVT' => 43200,
-        'TWT' => 28800,
-        'UYST' => -7200,
-        'UYT' => -10800,
-        'UZT' => 18000,
-        'VET' => -14400,
-        'VLAST' => 39600,
-        'VLAT' => 36000,
-        'VOST' => 21600,
-        'VUT' => 39600,
-        'WAST' => 7200,
-        'WAT' => 3600,
-        'WDT' => 32400,
-        'WEST' => 3600,
-        'WFT' => 43200,
-        'WIB' => 25200,
-        'WIT' => 32400,
-        'WITA' => 28800,
-        'WKST' => 18000,
-        'WST' => 28800,
-        'YAKST' => 36000,
-        'YAKT' => 32400,
-        'YAPT' => 36000,
-        'YEKST' => 21600,
-        'YEKT' => 18000,
-    ];
-
-    /**
-     * Cached PCRE for Date::$day
-     *
-     * @access protected
-     * @var string
-     */
-    public $day_pcre;
-
-    /**
-     * Cached PCRE for Date::$month
-     *
-     * @access protected
-     * @var string
-     */
-    public $month_pcre;
-
-    /**
-     * Array of user-added callback methods
-     *
-     * @access private
-     * @var array
-     */
-    public $built_in = [];
-
-    /**
-     * Array of user-added callback methods
-     *
-     * @access private
-     * @var array
-     */
-    public $user = [];
-
-    /**
-     * Create new Date object, and set self::day_pcre,
-     * self::month_pcre, and self::built_in
-     *
-     * @access private
-     */
-    public function __construct()
-    {
-        $this->day_pcre = '(' . implode('|', array_keys($this->day)) . ')';
-        $this->month_pcre = '(' . implode('|', array_keys($this->month)) . ')';
-
-        static $cache;
-        if (!isset($cache[get_class($this)])) {
-            $all_methods = get_class_methods($this);
-
-            foreach ($all_methods as $method) {
-                if (strtolower(substr($method, 0, 5)) === 'date_') {
-                    $cache[get_class($this)][] = $method;
-                }
-            }
-        }
-
-        foreach ($cache[get_class($this)] as $method) {
-            $this->built_in[] = $method;
-        }
-    }
-
-    /**
-     * Get the object
-     *
-     * @access public
-     */
-    public static function get()
-    {
-        static $object;
-        if (!$object) {
-            $object = new Date();
-        }
-        return $object;
-    }
-
-    /**
-     * Parse a date
-     *
-     * @final
-     * @access public
-     * @param string $date Date to parse
-     * @return int Timestamp corresponding to date string, or false on failure
-     */
-    public function parse($date)
-    {
-        foreach ($this->user as $method) {
-            if (($returned = call_user_func($method, $date)) !== false) {
-                return $returned;
-            }
-        }
-
-        foreach ($this->built_in as $method) {
-            if (($returned = call_user_func([$this, $method], $date)) !== false) {
-                return $returned;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Add a callback method to parse a date
-     *
-     * @final
-     * @access public
-     * @param callable $callback
-     */
-    public function add_callback($callback)
-    {
-        if (is_callable($callback)) {
-            $this->user[] = $callback;
-        } else {
-            trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
-        }
-    }
-
-    /**
-     * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
-     * well as allowing any of upper or lower case "T", horizontal tabs, or
-     * spaces to be used as the time separator (including more than one))
-     *
-     * @access protected
-     * @return int Timestamp
-     */
-    public function date_w3cdtf($date)
-    {
-        $pcre = <<<'PCRE'
-            /
-            ^
-            (?P<year>[0-9]{4})
-            (?:
-                -?
-                (?P<month>[0-9]{2})
-                (?:
-                    -?
-                    (?P<day>[0-9]{2})
-                    (?:
-                        [Tt\x09\x20]+
-                        (?P<hour>[0-9]{2})
-                        (?:
-                            :?
-                            (?P<minute>[0-9]{2})
-                            (?:
-                                :?
-                                (?P<second>[0-9]{2})
-                                (?:
-                                    .
-                                    (?P<second_fraction>[0-9]*)
-                                )?
-                            )?
-                        )?
-                        (?:
-                            (?P<zulu>Z)
-                            |   (?P<tz_sign>[+\-])
-                                (?P<tz_hour>[0-9]{1,2})
-                                :?
-                                (?P<tz_minute>[0-9]{1,2})
-                        )
-                    )?
-                )?
-            )?
-            $
-            /x
-PCRE;
-        if (preg_match($pcre, $date, $match)) {
-            // Fill in empty matches and convert to proper types.
-            $year = (int) $match['year'];
-            $month = isset($match['month']) ? (int) $match['month'] : 1;
-            $day = isset($match['day']) ? (int) $match['day'] : 1;
-            $hour = isset($match['hour']) ? (int) $match['hour'] : 0;
-            $minute = isset($match['minute']) ? (int) $match['minute'] : 0;
-            $second = isset($match['second']) ? (int) $match['second'] : 0;
-            $second_fraction = isset($match['second_fraction']) ? ((int) $match['second_fraction']) / (10 ** strlen($match['second_fraction'])) : 0;
-            $tz_sign = ($match['tz_sign'] ?? '') === '-' ? -1 : 1;
-            $tz_hour = isset($match['tz_hour']) ? (int) $match['tz_hour'] : 0;
-            $tz_minute = isset($match['tz_minute']) ? (int) $match['tz_minute'] : 0;
-
-            // Numeric timezone
-            $timezone = $tz_hour * 3600;
-            $timezone += $tz_minute * 60;
-            $timezone *= $tz_sign;
-
-            // Convert the number of seconds to an integer, taking decimals into account
-            $second = (int) round($second + $second_fraction);
-
-            return gmmktime($hour, $minute, $second, $month, $day, $year) - $timezone;
-        }
-
-        return false;
-    }
-
-    /**
-     * Remove RFC822 comments
-     *
-     * @access protected
-     * @param string $data Data to strip comments from
-     * @return string Comment stripped string
-     */
-    public function remove_rfc2822_comments($string)
-    {
-        $string = (string) $string;
-        $position = 0;
-        $length = strlen($string);
-        $depth = 0;
-
-        $output = '';
-
-        while ($position < $length && ($pos = strpos($string, '(', $position)) !== false) {
-            $output .= substr($string, $position, $pos - $position);
-            $position = $pos + 1;
-            if ($pos === 0 || $string[$pos - 1] !== '\\') {
-                $depth++;
-                while ($depth && $position < $length) {
-                    $position += strcspn($string, '()', $position);
-                    if ($string[$position - 1] === '\\') {
-                        $position++;
-                        continue;
-                    } elseif (isset($string[$position])) {
-                        switch ($string[$position]) {
-                            case '(':
-                                $depth++;
-                                break;
-
-                            case ')':
-                                $depth--;
-                                break;
-                        }
-                        $position++;
-                    } else {
-                        break;
-                    }
-                }
-            } else {
-                $output .= '(';
-            }
-        }
-        $output .= substr($string, $position);
-
-        return $output;
-    }
-
-    /**
-     * Parse RFC2822's date format
-     *
-     * @access protected
-     * @return int Timestamp
-     */
-    public function date_rfc2822($date)
-    {
-        static $pcre;
-        if (!$pcre) {
-            $wsp = '[\x09\x20]';
-            $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
-            $optional_fws = $fws . '?';
-            $day_name = $this->day_pcre;
-            $month = $this->month_pcre;
-            $day = '([0-9]{1,2})';
-            $hour = $minute = $second = '([0-9]{2})';
-            $year = '([0-9]{2,4})';
-            $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
-            $character_zone = '([A-Z]{1,5})';
-            $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
-            $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
-        }
-        if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match)) {
-            /*
-            Capturing subpatterns:
-            1: Day name
-            2: Day
-            3: Month
-            4: Year
-            5: Hour
-            6: Minute
-            7: Second
-            8: Timezone ±
-            9: Timezone hours
-            10: Timezone minutes
-            11: Alphabetic timezone
-            */
-
-            // Find the month number
-            $month = $this->month[strtolower($match[3])];
-
-            // Numeric timezone
-            if ($match[8] !== '') {
-                $timezone = $match[9] * 3600;
-                $timezone += $match[10] * 60;
-                if ($match[8] === '-') {
-                    $timezone = 0 - $timezone;
-                }
-            }
-            // Character timezone
-            elseif (isset($this->timezone[strtoupper($match[11])])) {
-                $timezone = $this->timezone[strtoupper($match[11])];
-            }
-            // Assume everything else to be -0000
-            else {
-                $timezone = 0;
-            }
-
-            // Deal with 2/3 digit years
-            if ($match[4] < 50) {
-                $match[4] += 2000;
-            } elseif ($match[4] < 1000) {
-                $match[4] += 1900;
-            }
-
-            // Second is optional, if it is empty set it to zero
-            if ($match[7] !== '') {
-                $second = $match[7];
-            } else {
-                $second = 0;
-            }
-
-            return gmmktime(intval($match[5]), intval($match[6]), intval($second), intval($month), intval($match[2]), intval($match[4])) - $timezone;
-        }
-
-        return false;
-    }
-
-    /**
-     * Parse RFC850's date format
-     *
-     * @access protected
-     * @return int Timestamp
-     */
-    public function date_rfc850($date)
-    {
-        static $pcre;
-        if (!$pcre) {
-            $space = '[\x09\x20]+';
-            $day_name = $this->day_pcre;
-            $month = $this->month_pcre;
-            $day = '([0-9]{1,2})';
-            $year = $hour = $minute = $second = '([0-9]{2})';
-            $zone = '([A-Z]{1,5})';
-            $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
-        }
-        if (preg_match($pcre, $date, $match)) {
-            /*
-            Capturing subpatterns:
-            1: Day name
-            2: Day
-            3: Month
-            4: Year
-            5: Hour
-            6: Minute
-            7: Second
-            8: Timezone
-            */
-
-            // Month
-            $month = $this->month[strtolower($match[3])];
-
-            // Character timezone
-            if (isset($this->timezone[strtoupper($match[8])])) {
-                $timezone = $this->timezone[strtoupper($match[8])];
-            }
-            // Assume everything else to be -0000
-            else {
-                $timezone = 0;
-            }
-
-            // Deal with 2 digit year
-            if ($match[4] < 50) {
-                $match[4] += 2000;
-            } else {
-                $match[4] += 1900;
-            }
-
-            return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
-        }
-
-        return false;
-    }
-
-    /**
-     * Parse C99's asctime()'s date format
-     *
-     * @access protected
-     * @return int Timestamp
-     */
-    public function date_asctime($date)
-    {
-        static $pcre;
-        if (!$pcre) {
-            $space = '[\x09\x20]+';
-            $wday_name = $this->day_pcre;
-            $mon_name = $this->month_pcre;
-            $day = '([0-9]{1,2})';
-            $hour = $sec = $min = '([0-9]{2})';
-            $year = '([0-9]{4})';
-            $terminator = '\x0A?\x00?';
-            $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
-        }
-        if (preg_match($pcre, $date, $match)) {
-            /*
-            Capturing subpatterns:
-            1: Day name
-            2: Month
-            3: Day
-            4: Hour
-            5: Minute
-            6: Second
-            7: Year
-            */
-
-            $month = $this->month[strtolower($match[2])];
-            return gmmktime((int) $match[4], (int) $match[5], (int) $match[6], $month, (int) $match[3], (int) $match[7]);
-        }
-
-        return false;
-    }
-
-    /**
-     * Parse dates using strtotime()
-     *
-     * @access protected
-     * @return int Timestamp
-     */
-    public function date_strtotime($date)
-    {
-        $strtotime = strtotime($date);
-        if ($strtotime === -1 || $strtotime === false) {
-            return false;
-        }
-
-        return $strtotime;
-    }
-}
-
-class_alias('SimplePie\Parse\Date', 'SimplePie_Parse_Date');
-
-}
-
-namespace SimplePie {
-
-use SimplePie\XML\Declaration\Parser as DeclarationParser;
-
-/**
- * Parses XML into something sane
- *
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_parser_class()}
- *
- * @package SimplePie
- * @subpackage Parsing
- */
-class Parser implements RegistryAware
-{
-    public $error_code;
-    public $error_string;
-    public $current_line;
-    public $current_column;
-    public $current_byte;
-    public $separator = ' ';
-    public $namespace = [''];
-    public $element = [''];
-    public $xml_base = [''];
-    public $xml_base_explicit = [false];
-    public $xml_lang = [''];
-    public $data = [];
-    public $datas = [[]];
-    public $current_xhtml_construct = -1;
-    public $encoding;
-    protected $registry;
-
-    public function set_registry(\SimplePie\Registry $registry)/* : void */
-    {
-        $this->registry = $registry;
-    }
-
-    public function parse(&$data, $encoding, $url = '')
-    {
-        if (class_exists('DOMXpath') && function_exists('Mf2\parse')) {
-            $doc = new \DOMDocument();
-            @$doc->loadHTML($data);
-            $xpath = new \DOMXpath($doc);
-            // Check for both h-feed and h-entry, as both a feed with no entries
-            // and a list of entries without an h-feed wrapper are both valid.
-            $query = '//*[contains(concat(" ", @class, " "), " h-feed ") or '.
-                'contains(concat(" ", @class, " "), " h-entry ")]';
-            $result = $xpath->query($query);
-            if ($result->length !== 0) {
-                return $this->parse_microformats($data, $url);
-            }
-        }
-
-        // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
-        if (strtoupper($encoding) === 'US-ASCII') {
-            $this->encoding = 'UTF-8';
-        } else {
-            $this->encoding = $encoding;
-        }
-
-        // Strip BOM:
-        // UTF-32 Big Endian BOM
-        if (substr($data, 0, 4) === "\x00\x00\xFE\xFF") {
-            $data = substr($data, 4);
-        }
-        // UTF-32 Little Endian BOM
-        elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00") {
-            $data = substr($data, 4);
-        }
-        // UTF-16 Big Endian BOM
-        elseif (substr($data, 0, 2) === "\xFE\xFF") {
-            $data = substr($data, 2);
-        }
-        // UTF-16 Little Endian BOM
-        elseif (substr($data, 0, 2) === "\xFF\xFE") {
-            $data = substr($data, 2);
-        }
-        // UTF-8 BOM
-        elseif (substr($data, 0, 3) === "\xEF\xBB\xBF") {
-            $data = substr($data, 3);
-        }
-
-        if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false) {
-            $declaration = $this->registry->create(DeclarationParser::class, [substr($data, 5, $pos - 5)]);
-            if ($declaration->parse()) {
-                $data = substr($data, $pos + 2);
-                $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' ."\n". $this->declare_html_entities() . $data;
-            } else {
-                $this->error_string = 'SimplePie bug! Please report this!';
-                return false;
-            }
-        }
-
-        $return = true;
-
-        static $xml_is_sane = null;
-        if ($xml_is_sane === null) {
-            $parser_check = xml_parser_create();
-            xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
-            xml_parser_free($parser_check);
-            $xml_is_sane = isset($values[0]['value']);
-        }
-
-        // Create the parser
-        if ($xml_is_sane) {
-            $xml = xml_parser_create_ns($this->encoding, $this->separator);
-            xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
-            xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
-            xml_set_object($xml, $this);
-            xml_set_character_data_handler($xml, 'cdata');
-            xml_set_element_handler($xml, 'tag_open', 'tag_close');
-
-            // Parse!
-            $wrapper = @is_writable(sys_get_temp_dir()) ? 'php://temp' : 'php://memory';
-            if (($stream = fopen($wrapper, 'r+')) &&
-                fwrite($stream, $data) &&
-                rewind($stream)) {
-                //Parse by chunks not to use too much memory
-                do {
-                    $stream_data = fread($stream, 1048576);
-                    if (!xml_parse($xml, $stream_data === false ? '' : $stream_data, feof($stream))) {
-                        $this->error_code = xml_get_error_code($xml);
-                        $this->error_string = xml_error_string($this->error_code);
-                        $return = false;
-                        break;
-                    }
-                } while (!feof($stream));
-                fclose($stream);
-            } else {
-                $return = false;
-            }
-
-            $this->current_line = xml_get_current_line_number($xml);
-            $this->current_column = xml_get_current_column_number($xml);
-            $this->current_byte = xml_get_current_byte_index($xml);
-            xml_parser_free($xml);
-            return $return;
-        }
-
-        libxml_clear_errors();
-        $xml = new \XMLReader();
-        $xml->xml($data);
-        while (@$xml->read()) {
-            switch ($xml->nodeType) {
-                case constant('XMLReader::END_ELEMENT'):
-                    if ($xml->namespaceURI !== '') {
-                        $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
-                    } else {
-                        $tagName = $xml->localName;
-                    }
-                    $this->tag_close(null, $tagName);
-                    break;
-                case constant('XMLReader::ELEMENT'):
-                    $empty = $xml->isEmptyElement;
-                    if ($xml->namespaceURI !== '') {
-                        $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
-                    } else {
-                        $tagName = $xml->localName;
-                    }
-                    $attributes = [];
-                    while ($xml->moveToNextAttribute()) {
-                        if ($xml->namespaceURI !== '') {
-                            $attrName = $xml->namespaceURI . $this->separator . $xml->localName;
-                        } else {
-                            $attrName = $xml->localName;
-                        }
-                        $attributes[$attrName] = $xml->value;
-                    }
-                    $this->tag_open(null, $tagName, $attributes);
-                    if ($empty) {
-                        $this->tag_close(null, $tagName);
-                    }
-                    break;
-                case constant('XMLReader::TEXT'):
-
-                case constant('XMLReader::CDATA'):
-                    $this->cdata(null, $xml->value);
-                    break;
-            }
-        }
-        if ($error = libxml_get_last_error()) {
-            $this->error_code = $error->code;
-            $this->error_string = $error->message;
-            $this->current_line = $error->line;
-            $this->current_column = $error->column;
-            return false;
-        }
-
-        return true;
-    }
-
-    public function get_error_code()
-    {
-        return $this->error_code;
-    }
-
-    public function get_error_string()
-    {
-        return $this->error_string;
-    }
-
-    public function get_current_line()
-    {
-        return $this->current_line;
-    }
-
-    public function get_current_column()
-    {
-        return $this->current_column;
-    }
-
-    public function get_current_byte()
-    {
-        return $this->current_byte;
-    }
-
-    public function get_data()
-    {
-        return $this->data;
-    }
-
-    public function tag_open($parser, $tag, $attributes)
-    {
-        [$this->namespace[], $this->element[]] = $this->split_ns($tag);
-
-        $attribs = [];
-        foreach ($attributes as $name => $value) {
-            [$attrib_namespace, $attribute] = $this->split_ns($name);
-            $attribs[$attrib_namespace][$attribute] = $value;
-        }
-
-        if (isset($attribs[\SimplePie\SimplePie::NAMESPACE_XML]['base'])) {
-            $base = $this->registry->call(Misc::class, 'absolutize_url', [$attribs[\SimplePie\SimplePie::NAMESPACE_XML]['base'], end($this->xml_base)]);
-            if ($base !== false) {
-                $this->xml_base[] = $base;
-                $this->xml_base_explicit[] = true;
-            }
-        } else {
-            $this->xml_base[] = end($this->xml_base);
-            $this->xml_base_explicit[] = end($this->xml_base_explicit);
-        }
-
-        if (isset($attribs[\SimplePie\SimplePie::NAMESPACE_XML]['lang'])) {
-            $this->xml_lang[] = $attribs[\SimplePie\SimplePie::NAMESPACE_XML]['lang'];
-        } else {
-            $this->xml_lang[] = end($this->xml_lang);
-        }
-
-        if ($this->current_xhtml_construct >= 0) {
-            $this->current_xhtml_construct++;
-            if (end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_XHTML) {
-                $this->data['data'] .= '<' . end($this->element);
-                if (isset($attribs[''])) {
-                    foreach ($attribs[''] as $name => $value) {
-                        $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
-                    }
-                }
-                $this->data['data'] .= '>';
-            }
-        } else {
-            $this->datas[] =& $this->data;
-            $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
-            $this->data = ['data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang)];
-            if ((end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_ATOM_03 && in_array(end($this->element), ['title', 'tagline', 'copyright', 'info', 'summary', 'content']) && isset($attribs['']['mode']) && $attribs['']['mode'] === 'xml')
-            || (end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_ATOM_10 && in_array(end($this->element), ['rights', 'subtitle', 'summary', 'info', 'title', 'content']) && isset($attribs['']['type']) && $attribs['']['type'] === 'xhtml')
-            || (end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_RSS_20 && in_array(end($this->element), ['title']))
-            || (end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_RSS_090 && in_array(end($this->element), ['title']))
-            || (end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_RSS_10 && in_array(end($this->element), ['title']))) {
-                $this->current_xhtml_construct = 0;
-            }
-        }
-    }
-
-    public function cdata($parser, $cdata)
-    {
-        if ($this->current_xhtml_construct >= 0) {
-            $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
-        } else {
-            $this->data['data'] .= $cdata;
-        }
-    }
-
-    public function tag_close($parser, $tag)
-    {
-        if ($this->current_xhtml_construct >= 0) {
-            $this->current_xhtml_construct--;
-            if (end($this->namespace) === \SimplePie\SimplePie::NAMESPACE_XHTML && !in_array(end($this->element), ['area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param'])) {
-                $this->data['data'] .= '</' . end($this->element) . '>';
-            }
-        }
-        if ($this->current_xhtml_construct === -1) {
-            $this->data =& $this->datas[count($this->datas) - 1];
-            array_pop($this->datas);
-        }
-
-        array_pop($this->element);
-        array_pop($this->namespace);
-        array_pop($this->xml_base);
-        array_pop($this->xml_base_explicit);
-        array_pop($this->xml_lang);
-    }
-
-    public function split_ns($string)
-    {
-        static $cache = [];
-        if (!isset($cache[$string])) {
-            if ($pos = strpos($string, $this->separator)) {
-                static $separator_length;
-                if (!$separator_length) {
-                    $separator_length = strlen($this->separator);
-                }
-                $namespace = substr($string, 0, $pos);
-                $local_name = substr($string, $pos + $separator_length);
-                if (strtolower($namespace) === \SimplePie\SimplePie::NAMESPACE_ITUNES) {
-                    $namespace = \SimplePie\SimplePie::NAMESPACE_ITUNES;
-                }
-
-                // Normalize the Media RSS namespaces
-                if ($namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG ||
-                    $namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG2 ||
-                    $namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG3 ||
-                    $namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG4 ||
-                    $namespace === \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG5) {
-                    $namespace = \SimplePie\SimplePie::NAMESPACE_MEDIARSS;
-                }
-                $cache[$string] = [$namespace, $local_name];
-            } else {
-                $cache[$string] = ['', $string];
-            }
-        }
-        return $cache[$string];
-    }
-
-    private function parse_hcard($data, $category = false)
-    {
-        $name = '';
-        $link = '';
-        // Check if h-card is set and pass that information on in the link.
-        if (isset($data['type']) && in_array('h-card', $data['type'])) {
-            if (isset($data['properties']['name'][0])) {
-                $name = $data['properties']['name'][0];
-            }
-            if (isset($data['properties']['url'][0])) {
-                $link = $data['properties']['url'][0];
-                if ($name === '') {
-                    $name = $link;
-                } else {
-                    // can't have commas in categories.
-                    $name = str_replace(',', '', $name);
-                }
-                $person_tag = $category ? '<span class="person-tag"></span>' : '';
-                return '<a class="h-card" href="'.$link.'">'.$person_tag.$name.'</a>';
-            }
-        }
-        return $data['value'] ?? '';
-    }
-
-    private function parse_microformats(&$data, $url)
-    {
-        $feed_title = '';
-        $feed_author = null;
-        $author_cache = [];
-        $items = [];
-        $entries = [];
-        $mf = \Mf2\parse($data, $url);
-        // First look for an h-feed.
-        $h_feed = [];
-        foreach ($mf['items'] as $mf_item) {
-            if (in_array('h-feed', $mf_item['type'])) {
-                $h_feed = $mf_item;
-                break;
-            }
-            // Also look for h-feed or h-entry in the children of each top level item.
-            if (!isset($mf_item['children'][0]['type'])) {
-                continue;
-            }
-            if (in_array('h-feed', $mf_item['children'][0]['type'])) {
-                $h_feed = $mf_item['children'][0];
-                // In this case the parent of the h-feed may be an h-card, so use it as
-                // the feed_author.
-                if (in_array('h-card', $mf_item['type'])) {
-                    $feed_author = $mf_item;
-                }
-                break;
-            } elseif (in_array('h-entry', $mf_item['children'][0]['type'])) {
-                $entries = $mf_item['children'];
-                // In this case the parent of the h-entry list may be an h-card, so use
-                // it as the feed_author.
-                if (in_array('h-card', $mf_item['type'])) {
-                    $feed_author = $mf_item;
-                }
-                break;
-            }
-        }
-        if (isset($h_feed['children'])) {
-            $entries = $h_feed['children'];
-            // Also set the feed title and store author from the h-feed if available.
-            if (isset($mf['items'][0]['properties']['name'][0])) {
-                $feed_title = $mf['items'][0]['properties']['name'][0];
-            }
-            if (isset($mf['items'][0]['properties']['author'][0])) {
-                $feed_author = $mf['items'][0]['properties']['author'][0];
-            }
-        } elseif (count($entries) === 0) {
-            $entries = $mf['items'];
-        }
-        for ($i = 0; $i < count($entries); $i++) {
-            $entry = $entries[$i];
-            if (in_array('h-entry', $entry['type'])) {
-                $item = [];
-                $title = '';
-                $description = '';
-                if (isset($entry['properties']['url'][0])) {
-                    $link = $entry['properties']['url'][0];
-                    if (isset($link['value'])) {
-                        $link = $link['value'];
-                    }
-                    $item['link'] = [['data' => $link]];
-                }
-                if (isset($entry['properties']['uid'][0])) {
-                    $guid = $entry['properties']['uid'][0];
-                    if (isset($guid['value'])) {
-                        $guid = $guid['value'];
-                    }
-                    $item['guid'] = [['data' => $guid]];
-                }
-                if (isset($entry['properties']['name'][0])) {
-                    $title = $entry['properties']['name'][0];
-                    if (isset($title['value'])) {
-                        $title = $title['value'];
-                    }
-                    $item['title'] = [['data' => $title]];
-                }
-                if (isset($entry['properties']['author'][0]) || isset($feed_author)) {
-                    // author is a special case, it can be plain text or an h-card array.
-                    // If it's plain text it can also be a url that should be followed to
-                    // get the actual h-card.
-                    $author = $entry['properties']['author'][0] ?? $feed_author;
-                    if (!is_string($author)) {
-                        $author = $this->parse_hcard($author);
-                    } elseif (strpos($author, 'http') === 0) {
-                        if (isset($author_cache[$author])) {
-                            $author = $author_cache[$author];
-                        } else {
-                            $mf = \Mf2\fetch($author);
-                            foreach ($mf['items'] as $hcard) {
-                                // Only interested in an h-card by itself in this case.
-                                if (!in_array('h-card', $hcard['type'])) {
-                                    continue;
-                                }
-                                // It must have a url property matching what we fetched.
-                                if (!isset($hcard['properties']['url']) ||
-                                        !(in_array($author, $hcard['properties']['url']))) {
-                                    continue;
-                                }
-                                // Save parse_hcard the trouble of finding the correct url.
-                                $hcard['properties']['url'][0] = $author;
-                                // Cache this h-card for the next h-entry to check.
-                                $author_cache[$author] = $this->parse_hcard($hcard);
-                                $author = $author_cache[$author];
-                                break;
-                            }
-                        }
-                    }
-                    $item['author'] = [['data' => $author]];
-                }
-                if (isset($entry['properties']['photo'][0])) {
-                    // If a photo is also in content, don't need to add it again here.
-                    $content = '';
-                    if (isset($entry['properties']['content'][0]['html'])) {
-                        $content = $entry['properties']['content'][0]['html'];
-                    }
-                    $photo_list = [];
-                    for ($j = 0; $j < count($entry['properties']['photo']); $j++) {
-                        $photo = $entry['properties']['photo'][$j];
-                        if (!empty($photo) && strpos($content, $photo) === false) {
-                            $photo_list[] = $photo;
-                        }
-                    }
-                    // When there's more than one photo show the first and use a lightbox.
-                    // Need a permanent, unique name for the image set, but don't have
-                    // anything unique except for the content itself, so use that.
-                    $count = count($photo_list);
-                    if ($count > 1) {
-                        $image_set_id = preg_replace('/[[:^alnum:]]/', '', $photo_list[0]);
-                        $description = '<p>';
-                        for ($j = 0; $j < $count; $j++) {
-                            $hidden = $j === 0 ? '' : 'class="hidden" ';
-                            $description .= '<a href="'.$photo_list[$j].'" '.$hidden.
-                                'data-lightbox="image-set-'.$image_set_id.'">'.
-                                '<img src="'.$photo_list[$j].'"></a>';
-                        }
-                        $description .= '<br><b>'.$count.' photos</b></p>';
-                    } elseif ($count == 1) {
-                        $description = '<p><img src="'.$photo_list[0].'"></p>';
-                    }
-                }
-                if (isset($entry['properties']['content'][0]['html'])) {
-                    // e-content['value'] is the same as p-name when they are on the same
-                    // element. Use this to replace title with a strip_tags version so
-                    // that alt text from images is not included in the title.
-                    if ($entry['properties']['content'][0]['value'] === $title) {
-                        $title = strip_tags($entry['properties']['content'][0]['html']);
-                        $item['title'] = [['data' => $title]];
-                    }
-                    $description .= $entry['properties']['content'][0]['html'];
-                    if (isset($entry['properties']['in-reply-to'][0])) {
-                        $in_reply_to = '';
-                        if (is_string($entry['properties']['in-reply-to'][0])) {
-                            $in_reply_to = $entry['properties']['in-reply-to'][0];
-                        } elseif (isset($entry['properties']['in-reply-to'][0]['value'])) {
-                            $in_reply_to = $entry['properties']['in-reply-to'][0]['value'];
-                        }
-                        if ($in_reply_to !== '') {
-                            $description .= '<p><span class="in-reply-to"></span> '.
-                                '<a href="'.$in_reply_to.'">'.$in_reply_to.'</a><p>';
-                        }
-                    }
-                    $item['description'] = [['data' => $description]];
-                }
-                if (isset($entry['properties']['category'])) {
-                    $category_csv = '';
-                    // Categories can also contain h-cards.
-                    foreach ($entry['properties']['category'] as $category) {
-                        if ($category_csv !== '') {
-                            $category_csv .= ', ';
-                        }
-                        if (is_string($category)) {
-                            // Can't have commas in categories.
-                            $category_csv .= str_replace(',', '', $category);
-                        } else {
-                            $category_csv .= $this->parse_hcard($category, true);
-                        }
-                    }
-                    $item['category'] = [['data' => $category_csv]];
-                }
-                if (isset($entry['properties']['published'][0])) {
-                    $timestamp = strtotime($entry['properties']['published'][0]);
-                    $pub_date = date('F j Y g:ia', $timestamp).' GMT';
-                    $item['pubDate'] = [['data' => $pub_date]];
-                }
-                // The title and description are set to the empty string to represent
-                // a deleted item (which also makes it an invalid rss item).
-                if (isset($entry['properties']['deleted'][0])) {
-                    $item['title'] = [['data' => '']];
-                    $item['description'] = [['data' => '']];
-                }
-                $items[] = ['child' => ['' => $item]];
-            }
-        }
-        // Mimic RSS data format when storing microformats.
-        $link = [['data' => $url]];
-        $image = '';
-        if (!is_string($feed_author) &&
-                isset($feed_author['properties']['photo'][0])) {
-            $image = [['child' => ['' => ['url' =>
-                [['data' => $feed_author['properties']['photo'][0]]]]]]];
-        }
-        // Use the name given for the h-feed, or get the title from the html.
-        if ($feed_title !== '') {
-            $feed_title = [['data' => htmlspecialchars($feed_title)]];
-        } elseif ($position = strpos($data, '<title>')) {
-            $start = $position < 200 ? 0 : $position - 200;
-            $check = substr($data, $start, 400);
-            $matches = [];
-            if (preg_match('/<title>(.+)<\/title>/', $check, $matches)) {
-                $feed_title = [['data' => htmlspecialchars($matches[1])]];
-            }
-        }
-        $channel = ['channel' => [['child' => ['' =>
-            ['link' => $link, 'image' => $image, 'title' => $feed_title,
-                  'item' => $items]]]]];
-        $rss = [['attribs' => ['' => ['version' => '2.0']],
-                           'child' => ['' => $channel]]];
-        $this->data = ['child' => ['' => ['rss' => $rss]]];
-        return true;
-    }
-
-    private function declare_html_entities()
-    {
-        // This is required because the RSS specification says that entity-encoded
-        // html is allowed, but the xml specification says they must be declared.
-        return '<!DOCTYPE html [ <!ENTITY nbsp "&#x00A0;"> <!ENTITY iexcl "&#x00A1;"> <!ENTITY cent "&#x00A2;"> <!ENTITY pound "&#x00A3;"> <!ENTITY curren "&#x00A4;"> <!ENTITY yen "&#x00A5;"> <!ENTITY brvbar "&#x00A6;"> <!ENTITY sect "&#x00A7;"> <!ENTITY uml "&#x00A8;"> <!ENTITY copy "&#x00A9;"> <!ENTITY ordf "&#x00AA;"> <!ENTITY laquo "&#x00AB;"> <!ENTITY not "&#x00AC;"> <!ENTITY shy "&#x00AD;"> <!ENTITY reg "&#x00AE;"> <!ENTITY macr "&#x00AF;"> <!ENTITY deg "&#x00B0;"> <!ENTITY plusmn "&#x00B1;"> <!ENTITY sup2 "&#x00B2;"> <!ENTITY sup3 "&#x00B3;"> <!ENTITY acute "&#x00B4;"> <!ENTITY micro "&#x00B5;"> <!ENTITY para "&#x00B6;"> <!ENTITY middot "&#x00B7;"> <!ENTITY cedil "&#x00B8;"> <!ENTITY sup1 "&#x00B9;"> <!ENTITY ordm "&#x00BA;"> <!ENTITY raquo "&#x00BB;"> <!ENTITY frac14 "&#x00BC;"> <!ENTITY frac12 "&#x00BD;"> <!ENTITY frac34 "&#x00BE;"> <!ENTITY iquest "&#x00BF;"> <!ENTITY Agrave "&#x00C0;"> <!ENTITY Aacute "&#x00C1;"> <!ENTITY Acirc "&#x00C2;"> <!ENTITY Atilde "&#x00C3;"> <!ENTITY Auml "&#x00C4;"> <!ENTITY Aring "&#x00C5;"> <!ENTITY AElig "&#x00C6;"> <!ENTITY Ccedil "&#x00C7;"> <!ENTITY Egrave "&#x00C8;"> <!ENTITY Eacute "&#x00C9;"> <!ENTITY Ecirc "&#x00CA;"> <!ENTITY Euml "&#x00CB;"> <!ENTITY Igrave "&#x00CC;"> <!ENTITY Iacute "&#x00CD;"> <!ENTITY Icirc "&#x00CE;"> <!ENTITY Iuml "&#x00CF;"> <!ENTITY ETH "&#x00D0;"> <!ENTITY Ntilde "&#x00D1;"> <!ENTITY Ograve "&#x00D2;"> <!ENTITY Oacute "&#x00D3;"> <!ENTITY Ocirc "&#x00D4;"> <!ENTITY Otilde "&#x00D5;"> <!ENTITY Ouml "&#x00D6;"> <!ENTITY times "&#x00D7;"> <!ENTITY Oslash "&#x00D8;"> <!ENTITY Ugrave "&#x00D9;"> <!ENTITY Uacute "&#x00DA;"> <!ENTITY Ucirc "&#x00DB;"> <!ENTITY Uuml "&#x00DC;"> <!ENTITY Yacute "&#x00DD;"> <!ENTITY THORN "&#x00DE;"> <!ENTITY szlig "&#x00DF;"> <!ENTITY agrave "&#x00E0;"> <!ENTITY aacute "&#x00E1;"> <!ENTITY acirc "&#x00E2;"> <!ENTITY atilde "&#x00E3;"> <!ENTITY auml "&#x00E4;"> <!ENTITY aring "&#x00E5;"> <!ENTITY aelig "&#x00E6;"> <!ENTITY ccedil "&#x00E7;"> <!ENTITY egrave "&#x00E8;"> <!ENTITY eacute "&#x00E9;"> <!ENTITY ecirc "&#x00EA;"> <!ENTITY euml "&#x00EB;"> <!ENTITY igrave "&#x00EC;"> <!ENTITY iacute "&#x00ED;"> <!ENTITY icirc "&#x00EE;"> <!ENTITY iuml "&#x00EF;"> <!ENTITY eth "&#x00F0;"> <!ENTITY ntilde "&#x00F1;"> <!ENTITY ograve "&#x00F2;"> <!ENTITY oacute "&#x00F3;"> <!ENTITY ocirc "&#x00F4;"> <!ENTITY otilde "&#x00F5;"> <!ENTITY ouml "&#x00F6;"> <!ENTITY divide "&#x00F7;"> <!ENTITY oslash "&#x00F8;"> <!ENTITY ugrave "&#x00F9;"> <!ENTITY uacute "&#x00FA;"> <!ENTITY ucirc "&#x00FB;"> <!ENTITY uuml "&#x00FC;"> <!ENTITY yacute "&#x00FD;"> <!ENTITY thorn "&#x00FE;"> <!ENTITY yuml "&#x00FF;"> <!ENTITY OElig "&#x0152;"> <!ENTITY oelig "&#x0153;"> <!ENTITY Scaron "&#x0160;"> <!ENTITY scaron "&#x0161;"> <!ENTITY Yuml "&#x0178;"> <!ENTITY fnof "&#x0192;"> <!ENTITY circ "&#x02C6;"> <!ENTITY tilde "&#x02DC;"> <!ENTITY Alpha "&#x0391;"> <!ENTITY Beta "&#x0392;"> <!ENTITY Gamma "&#x0393;"> <!ENTITY Epsilon "&#x0395;"> <!ENTITY Zeta "&#x0396;"> <!ENTITY Eta "&#x0397;"> <!ENTITY Theta "&#x0398;"> <!ENTITY Iota "&#x0399;"> <!ENTITY Kappa "&#x039A;"> <!ENTITY Lambda "&#x039B;"> <!ENTITY Mu "&#x039C;"> <!ENTITY Nu "&#x039D;"> <!ENTITY Xi "&#x039E;"> <!ENTITY Omicron "&#x039F;"> <!ENTITY Pi "&#x03A0;"> <!ENTITY Rho "&#x03A1;"> <!ENTITY Sigma "&#x03A3;"> <!ENTITY Tau "&#x03A4;"> <!ENTITY Upsilon "&#x03A5;"> <!ENTITY Phi "&#x03A6;"> <!ENTITY Chi "&#x03A7;"> <!ENTITY Psi "&#x03A8;"> <!ENTITY Omega "&#x03A9;"> <!ENTITY alpha "&#x03B1;"> <!ENTITY beta "&#x03B2;"> <!ENTITY gamma "&#x03B3;"> <!ENTITY delta "&#x03B4;"> <!ENTITY epsilon "&#x03B5;"> <!ENTITY zeta "&#x03B6;"> <!ENTITY eta "&#x03B7;"> <!ENTITY theta "&#x03B8;"> <!ENTITY iota "&#x03B9;"> <!ENTITY kappa "&#x03BA;"> <!ENTITY lambda "&#x03BB;"> <!ENTITY mu "&#x03BC;"> <!ENTITY nu "&#x03BD;"> <!ENTITY xi "&#x03BE;"> <!ENTITY omicron "&#x03BF;"> <!ENTITY pi "&#x03C0;"> <!ENTITY rho "&#x03C1;"> <!ENTITY sigmaf "&#x03C2;"> <!ENTITY sigma "&#x03C3;"> <!ENTITY tau "&#x03C4;"> <!ENTITY upsilon "&#x03C5;"> <!ENTITY phi "&#x03C6;"> <!ENTITY chi "&#x03C7;"> <!ENTITY psi "&#x03C8;"> <!ENTITY omega "&#x03C9;"> <!ENTITY thetasym "&#x03D1;"> <!ENTITY upsih "&#x03D2;"> <!ENTITY piv "&#x03D6;"> <!ENTITY ensp "&#x2002;"> <!ENTITY emsp "&#x2003;"> <!ENTITY thinsp "&#x2009;"> <!ENTITY zwnj "&#x200C;"> <!ENTITY zwj "&#x200D;"> <!ENTITY lrm "&#x200E;"> <!ENTITY rlm "&#x200F;"> <!ENTITY ndash "&#x2013;"> <!ENTITY mdash "&#x2014;"> <!ENTITY lsquo "&#x2018;"> <!ENTITY rsquo "&#x2019;"> <!ENTITY sbquo "&#x201A;"> <!ENTITY ldquo "&#x201C;"> <!ENTITY rdquo "&#x201D;"> <!ENTITY bdquo "&#x201E;"> <!ENTITY dagger "&#x2020;"> <!ENTITY Dagger "&#x2021;"> <!ENTITY bull "&#x2022;"> <!ENTITY hellip "&#x2026;"> <!ENTITY permil "&#x2030;"> <!ENTITY prime "&#x2032;"> <!ENTITY Prime "&#x2033;"> <!ENTITY lsaquo "&#x2039;"> <!ENTITY rsaquo "&#x203A;"> <!ENTITY oline "&#x203E;"> <!ENTITY frasl "&#x2044;"> <!ENTITY euro "&#x20AC;"> <!ENTITY image "&#x2111;"> <!ENTITY weierp "&#x2118;"> <!ENTITY real "&#x211C;"> <!ENTITY trade "&#x2122;"> <!ENTITY alefsym "&#x2135;"> <!ENTITY larr "&#x2190;"> <!ENTITY uarr "&#x2191;"> <!ENTITY rarr "&#x2192;"> <!ENTITY darr "&#x2193;"> <!ENTITY harr "&#x2194;"> <!ENTITY crarr "&#x21B5;"> <!ENTITY lArr "&#x21D0;"> <!ENTITY uArr "&#x21D1;"> <!ENTITY rArr "&#x21D2;"> <!ENTITY dArr "&#x21D3;"> <!ENTITY hArr "&#x21D4;"> <!ENTITY forall "&#x2200;"> <!ENTITY part "&#x2202;"> <!ENTITY exist "&#x2203;"> <!ENTITY empty "&#x2205;"> <!ENTITY nabla "&#x2207;"> <!ENTITY isin "&#x2208;"> <!ENTITY notin "&#x2209;"> <!ENTITY ni "&#x220B;"> <!ENTITY prod "&#x220F;"> <!ENTITY sum "&#x2211;"> <!ENTITY minus "&#x2212;"> <!ENTITY lowast "&#x2217;"> <!ENTITY radic "&#x221A;"> <!ENTITY prop "&#x221D;"> <!ENTITY infin "&#x221E;"> <!ENTITY ang "&#x2220;"> <!ENTITY and "&#x2227;"> <!ENTITY or "&#x2228;"> <!ENTITY cap "&#x2229;"> <!ENTITY cup "&#x222A;"> <!ENTITY int "&#x222B;"> <!ENTITY there4 "&#x2234;"> <!ENTITY sim "&#x223C;"> <!ENTITY cong "&#x2245;"> <!ENTITY asymp "&#x2248;"> <!ENTITY ne "&#x2260;"> <!ENTITY equiv "&#x2261;"> <!ENTITY le "&#x2264;"> <!ENTITY ge "&#x2265;"> <!ENTITY sub "&#x2282;"> <!ENTITY sup "&#x2283;"> <!ENTITY nsub "&#x2284;"> <!ENTITY sube "&#x2286;"> <!ENTITY supe "&#x2287;"> <!ENTITY oplus "&#x2295;"> <!ENTITY otimes "&#x2297;"> <!ENTITY perp "&#x22A5;"> <!ENTITY sdot "&#x22C5;"> <!ENTITY lceil "&#x2308;"> <!ENTITY rceil "&#x2309;"> <!ENTITY lfloor "&#x230A;"> <!ENTITY rfloor "&#x230B;"> <!ENTITY lang "&#x2329;"> <!ENTITY rang "&#x232A;"> <!ENTITY loz "&#x25CA;"> <!ENTITY spades "&#x2660;"> <!ENTITY clubs "&#x2663;"> <!ENTITY hearts "&#x2665;"> <!ENTITY diams "&#x2666;"> ]>';
-    }
-}
-
-class_alias('SimplePie\Parser', 'SimplePie_Parser');
-
-}
-
-namespace SimplePie {
-
-/**
- * Handles `<media:rating>` or `<itunes:explicit>` tags as defined in Media RSS and iTunes RSS respectively
- *
- * Used by {@see \SimplePie\Enclosure::get_rating()} and {@see \SimplePie\Enclosure::get_ratings()}
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_rating_class()}
- *
- * @package SimplePie
- * @subpackage API
- */
-class Rating
-{
-    /**
-     * Rating scheme
-     *
-     * @var string
-     * @see get_scheme()
-     */
-    public $scheme;
-
-    /**
-     * Rating value
-     *
-     * @var string
-     * @see get_value()
-     */
-    public $value;
-
-    /**
-     * Constructor, used to input the data
-     *
-     * For documentation on all the parameters, see the corresponding
-     * properties and their accessors
-     */
-    public function __construct($scheme = null, $value = null)
-    {
-        $this->scheme = $scheme;
-        $this->value = $value;
-    }
-
-    /**
-     * String-ified version
-     *
-     * @return string
-     */
-    public function __toString()
-    {
-        // There is no $this->data here
-        return md5(serialize($this));
-    }
-
-    /**
-     * Get the organizational scheme for the rating
-     *
-     * @return string|null
-     */
-    public function get_scheme()
-    {
-        if ($this->scheme !== null) {
-            return $this->scheme;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the value of the rating
-     *
-     * @return string|null
-     */
-    public function get_value()
-    {
-        if ($this->value !== null) {
-            return $this->value;
-        }
-
-        return null;
-    }
-}
-
-class_alias('SimplePie\Rating', 'SimplePie_Rating');
-
-}
-
-namespace SimplePie {
-
-use SimplePie\Content\Type\Sniffer;
-use SimplePie\Parse\Date;
-use SimplePie\XML\Declaration\Parser as DeclarationParser;
-
-/**
- * Handles creating objects and calling methods
- *
- * Access this via {@see \SimplePie\SimplePie::get_registry()}
- *
- * @package SimplePie
- */
-class Registry
-{
-    /**
-     * Default class mapping
-     *
-     * Overriding classes *must* subclass these.
-     *
-     * @var array<class-string, class-string>
-     */
-    protected $default = [
-        Cache::class => Cache::class,
-        Locator::class => Locator::class,
-        Parser::class => Parser::class,
-        File::class => File::class,
-        Sanitize::class => Sanitize::class,
-        Item::class => Item::class,
-        Author::class => Author::class,
-        Category::class => Category::class,
-        Enclosure::class => Enclosure::class,
-        Caption::class => Caption::class,
-        Copyright::class => Copyright::class,
-        Credit::class => Credit::class,
-        Rating::class => Rating::class,
-        Restriction::class => Restriction::class,
-        Sniffer::class => Sniffer::class,
-        Source::class => Source::class,
-        Misc::class => Misc::class,
-        DeclarationParser::class => DeclarationParser::class,
-        Date::class => Date::class,
-    ];
-
-    /**
-     * Class mapping
-     *
-     * @see register()
-     * @var array
-     */
-    protected $classes = [];
-
-    /**
-     * Legacy classes
-     *
-     * @see register()
-     * @var array<class-string>
-     */
-    protected $legacy = [];
-
-    /**
-     * Legacy types
-     *
-     * @see register()
-     * @var array<string, class-string>
-     */
-    private $legacyTypes = [
-        'Cache' => Cache::class,
-        'Locator' => Locator::class,
-        'Parser' => Parser::class,
-        'File' => File::class,
-        'Sanitize' => Sanitize::class,
-        'Item' => Item::class,
-        'Author' => Author::class,
-        'Category' => Category::class,
-        'Enclosure' => Enclosure::class,
-        'Caption' => Caption::class,
-        'Copyright' => Copyright::class,
-        'Credit' => Credit::class,
-        'Rating' => Rating::class,
-        'Restriction' => Restriction::class,
-        'Content_Type_Sniffer' => Sniffer::class,
-        'Source' => Source::class,
-        'Misc' => Misc::class,
-        'XML_Declaration_Parser' => DeclarationParser::class,
-        'Parse_Date' => Date::class,
-    ];
-
-    /**
-     * Constructor
-     *
-     * No-op
-     */
-    public function __construct()
-    {
-    }
-
-    /**
-     * Register a class
-     *
-     * @param string $type See {@see $default} for names
-     * @param class-string $class Class name, must subclass the corresponding default
-     * @param bool $legacy Whether to enable legacy support for this class
-     * @return bool Successfulness
-     */
-    public function register($type, $class, $legacy = false)
-    {
-        if (array_key_exists($type, $this->legacyTypes)) {
-            // trigger_error(sprintf('"%s"(): Using argument #1 ($type) with value "%s" is deprecated since SimplePie 1.8.0, use class-string "%s" instead.', __METHOD__, $type, $this->legacyTypes[$type]), \E_USER_DEPRECATED);
-
-            $type = $this->legacyTypes[$type];
-        }
-
-        if (! array_key_exists($type, $this->default)) {
-            return false;
-        }
-
-        if (!class_exists($class)) {
-            return false;
-        }
-
-        /** @var string */
-        $base_class = $this->default[$type];
-
-        if (!is_subclass_of($class, $base_class)) {
-            return false;
-        }
-
-        $this->classes[$type] = $class;
-
-        if ($legacy) {
-            $this->legacy[] = $class;
-        }
-
-        return true;
-    }
-
-    /**
-     * Get the class registered for a type
-     *
-     * Where possible, use {@see create()} or {@see call()} instead
-     *
-     * @template T
-     * @param class-string<T> $type
-     * @return class-string<T>|null
-     */
-    public function get_class($type)
-    {
-        if (array_key_exists($type, $this->legacyTypes)) {
-            // trigger_error(sprintf('"%s"(): Using argument #1 ($type) with value "%s" is deprecated since SimplePie 1.8.0, use class-string "%s" instead.', __METHOD__, $type, $this->legacyTypes[$type]), \E_USER_DEPRECATED);
-
-            $type = $this->legacyTypes[$type];
-        }
-
-        if (! array_key_exists($type, $this->default)) {
-            return null;
-        }
-
-        $class = $this->default[$type];
-
-        if (array_key_exists($type, $this->classes)) {
-            $class = $this->classes[$type];
-        }
-
-        return $class;
-    }
-
-    /**
-     * Create a new instance of a given type
-     *
-     * @template T class-string $type
-     * @param class-string<T> $type
-     * @param array $parameters Parameters to pass to the constructor
-     * @return T Instance of class
-     */
-    public function &create($type, $parameters = [])
-    {
-        $class = $this->get_class($type);
-
-        if (!method_exists($class, '__construct')) {
-            $instance = new $class();
-        } else {
-            $reflector = new \ReflectionClass($class);
-            $instance = $reflector->newInstanceArgs($parameters);
-        }
-
-        if ($instance instanceof RegistryAware) {
-            $instance->set_registry($this);
-        } elseif (method_exists($instance, 'set_registry')) {
-            trigger_error(sprintf('Using the method "set_registry()" without implementing "%s" is deprecated since SimplePie 1.8.0, implement "%s" in "%s".', RegistryAware::class, RegistryAware::class, $class), \E_USER_DEPRECATED);
-            $instance->set_registry($this);
-        }
-        return $instance;
-    }
-
-    /**
-     * Call a static method for a type
-     *
-     * @param class-string $type
-     * @param string $method
-     * @param array $parameters
-     * @return mixed
-     */
-    public function &call($type, $method, $parameters = [])
-    {
-        $class = $this->get_class($type);
-
-        if (in_array($class, $this->legacy)) {
-            switch ($type) {
-                case Cache::class:
-                    // For backwards compatibility with old non-static
-                    // Cache::create() methods in PHP < 8.0.
-                    // No longer supported as of PHP 8.0.
-                    if ($method === 'get_handler') {
-                        $result = @call_user_func_array([$class, 'create'], $parameters);
-                        return $result;
-                    }
-                    break;
-            }
-        }
-
-        $result = call_user_func_array([$class, $method], $parameters);
-        return $result;
-    }
-}
-
-class_alias('SimplePie\Registry', 'SimplePie_Registry');
-
-}
-
-namespace SimplePie {
-
-/**
- * Handles the injection of Registry into other class
- *
- * {@see \SimplePie\SimplePie::get_registry()}
- *
- * @package SimplePie
- */
-interface RegistryAware
-{
-    /**
-     * Set the Registry into the class
-     *
-     * @param Registry $registry
-     *
-     * @return void
-     */
-    public function set_registry(Registry $registry)/* : void */;
-}
-
-}
-
-namespace SimplePie {
-
-/**
- * Handles `<media:restriction>` as defined in Media RSS
- *
- * Used by {@see \SimplePie\Enclosure::get_restriction()} and {@see \SimplePie\Enclosure::get_restrictions()}
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_restriction_class()}
- *
- * @package SimplePie
- * @subpackage API
- */
-class Restriction
-{
-    /**
-     * Relationship ('allow'/'deny')
-     *
-     * @var string
-     * @see get_relationship()
-     */
-    public $relationship;
-
-    /**
-     * Type of restriction
-     *
-     * @var string
-     * @see get_type()
-     */
-    public $type;
-
-    /**
-     * Restricted values
-     *
-     * @var string
-     * @see get_value()
-     */
-    public $value;
-
-    /**
-     * Constructor, used to input the data
-     *
-     * For documentation on all the parameters, see the corresponding
-     * properties and their accessors
-     */
-    public function __construct($relationship = null, $type = null, $value = null)
-    {
-        $this->relationship = $relationship;
-        $this->type = $type;
-        $this->value = $value;
-    }
-
-    /**
-     * String-ified version
-     *
-     * @return string
-     */
-    public function __toString()
-    {
-        // There is no $this->data here
-        return md5(serialize($this));
-    }
-
-    /**
-     * Get the relationship
-     *
-     * @return string|null Either 'allow' or 'deny'
-     */
-    public function get_relationship()
-    {
-        if ($this->relationship !== null) {
-            return $this->relationship;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the type
-     *
-     * @return string|null
-     */
-    public function get_type()
-    {
-        if ($this->type !== null) {
-            return $this->type;
-        }
-
-        return null;
-    }
-
-    /**
-     * Get the list of restricted things
-     *
-     * @return string|null
-     */
-    public function get_value()
-    {
-        if ($this->value !== null) {
-            return $this->value;
-        }
-
-        return null;
-    }
-}
-
-class_alias('SimplePie\Restriction', 'SimplePie_Restriction');
-
-}
-
-namespace SimplePie {
-
-use InvalidArgumentException;
-use SimplePie\Cache\Base;
-use SimplePie\Cache\BaseDataCache;
-use SimplePie\Cache\CallableNameFilter;
-use SimplePie\Cache\DataCache;
-use SimplePie\Cache\NameFilter;
-
-/**
- * Used for data cleanup and post-processing
- *
- *
- * This class can be overloaded with {@see \SimplePie\SimplePie::set_sanitize_class()}
- *
- * @package SimplePie
- * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags
- */
-class Sanitize implements RegistryAware
-{
-    // Private vars
-    public $base;
-
-    // Options
-    public $remove_div = true;
-    public $image_handler = '';
-    public $strip_htmltags = ['base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'];
-    public $encode_instead_of_strip = false;
-    public $strip_attributes = ['bgsound', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'];
-    public $rename_attributes = [];
-    public $add_attributes = ['audio' => ['preload' => 'none'], 'iframe' => ['sandbox' => 'allow-scripts allow-same-origin'], 'video' => ['preload' => 'none']];
-    public $strip_comments = false;
-    public $output_encoding = 'UTF-8';
-    public $enable_cache = true;
-    public $cache_location = './cache';
-    public $cache_name_function = 'md5';
-
-    /**
-     * @var NameFilter
-     */
-    private $cache_namefilter;
-    public $timeout = 10;
-    public $useragent = '';
-    public $force_fsockopen = false;
-    public $replace_url_attributes = null;
-    public $registry;
-
-    /**
-     * @var DataCache|null
-     */
-    private $cache = null;
-
-    /**
-     * @var int Cache duration (in seconds)
-     */
-    private $cache_duration = 3600;
-
-    /**
-     * List of domains for which to force HTTPS.
-     * @see \SimplePie\Sanitize::set_https_domains()
-     * Array is a tree split at DNS levels. Example:
-     * array('biz' => true, 'com' => array('example' => true), 'net' => array('example' => array('www' => true)))
-     */
-    public $https_domains = [];
-
-    public function __construct()
-    {
-        // Set defaults
-        $this->set_url_replacements(null);
-    }
-
-    public function remove_div($enable = true)
-    {
-        $this->remove_div = (bool) $enable;
-    }
-
-    public function set_image_handler($page = false)
-    {
-        if ($page) {
-            $this->image_handler = (string) $page;
-        } else {
-            $this->image_handler = false;
-        }
-    }
-
-    public function set_registry(\SimplePie\Registry $registry)/* : void */
-    {
-        $this->registry = $registry;
-    }
-
-    public function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie\Cache', DataCache $cache = null)
-    {
-        if (isset($enable_cache)) {
-            $this->enable_cache = (bool) $enable_cache;
-        }
-
-        if ($cache_location) {
-            $this->cache_location = (string) $cache_location;
-        }
-
-        if (! is_string($cache_name_function) && ! is_object($cache_name_function) && ! $cache_name_function instanceof NameFilter) {
-            throw new InvalidArgumentException(sprintf(
-                '%s(): Argument #3 ($cache_name_function) must be of type %s',
-                __METHOD__,
-                NameFilter::class
-            ), 1);
-        }
-
-        // BC: $cache_name_function could be a callable as string
-        if (is_string($cache_name_function)) {
-            // trigger_error(sprintf('Providing $cache_name_function as string in "%s()" is deprecated since SimplePie 1.8.0, provide as "%s" instead.', __METHOD__, NameFilter::class), \E_USER_DEPRECATED);
-            $this->cache_name_function = (string) $cache_name_function;
-
-            $cache_name_function = new CallableNameFilter($cache_name_function);
-        }
-
-        $this->cache_namefilter = $cache_name_function;
-
-        if ($cache !== null) {
-            $this->cache = $cache;
-        }
-    }
-
-    public function pass_file_data($file_class = 'SimplePie\File', $timeout = 10, $useragent = '', $force_fsockopen = false)
-    {
-        if ($timeout) {
-            $this->timeout = (string) $timeout;
-        }
-
-        if ($useragent) {
-            $this->useragent = (string) $useragent;
-        }
-
-        if ($force_fsockopen) {
-            $this->force_fsockopen = (string) $force_fsockopen;
-        }
-    }
-
-    public function strip_htmltags($tags = ['base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'])
-    {
-        if ($tags) {
-            if (is_array($tags)) {
-                $this->strip_htmltags = $tags;
-            } else {
-                $this->strip_htmltags = explode(',', $tags);
-            }
-        } else {
-            $this->strip_htmltags = false;
-        }
-    }
-
-    public function encode_instead_of_strip($encode = false)
-    {
-        $this->encode_instead_of_strip = (bool) $encode;
-    }
-
-    public function rename_attributes($attribs = [])
-    {
-        if ($attribs) {
-            if (is_array($attribs)) {
-                $this->rename_attributes = $attribs;
-            } else {
-                $this->rename_attributes = explode(',', $attribs);
-            }
-        } else {
-            $this->rename_attributes = false;
-        }
-    }
-
-    public function strip_attributes($attribs = ['bgsound', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'])
-    {
-        if ($attribs) {
-            if (is_array($attribs)) {
-                $this->strip_attributes = $attribs;
-            } else {
-                $this->strip_attributes = explode(',', $attribs);
-            }
-        } else {
-            $this->strip_attributes = false;
-        }
-    }
-
-    public function add_attributes($attribs = ['audio' => ['preload' => 'none'], 'iframe' => ['sandbox' => 'allow-scripts allow-same-origin'], 'video' => ['preload' => 'none']])
-    {
-        if ($attribs) {
-            if (is_array($attribs)) {
-                $this->add_attributes = $attribs;
-            } else {
-                $this->add_attributes = explode(',', $attribs);
-            }
-        } else {
-            $this->add_attributes = false;
-        }
-    }
-
-    public function strip_comments($strip = false)
-    {
-        $this->strip_comments = (bool) $strip;
-    }
-
-    public function set_output_encoding($encoding = 'UTF-8')
-    {
-        $this->output_encoding = (string) $encoding;
-    }
-
-    /**
-     * Set element/attribute key/value pairs of HTML attributes
-     * containing URLs that need to be resolved relative to the feed
-     *
-     * Defaults to |a|@href, |area|@href, |audio|@src, |blockquote|@cite,
-     * |del|@cite, |form|@action, |img|@longdesc, |img|@src, |input|@src,
-     * |ins|@cite, |q|@cite, |source|@src, |video|@src
-     *
-     * @since 1.0
-     * @param array|null $element_attribute Element/attribute key/value pairs, null for default
-     */
-    public function set_url_replacements($element_attribute = null)
-    {
-        if ($element_attribute === null) {
-            $element_attribute = [
-                'a' => 'href',
-                'area' => 'href',
-                'audio' => 'src',
-                'blockquote' => 'cite',
-                'del' => 'cite',
-                'form' => 'action',
-                'img' => [
-                    'longdesc',
-                    'src'
-                ],
-                'input' => 'src',
-                'ins' => 'cite',
-                'q' => 'cite',
-                'source' => 'src',
-                'video' => [
-                    'poster',
-                    'src'
-                ]
-            ];
-        }
-        $this->replace_url_attributes = (array) $element_attribute;
-    }
-
-    /**
-     * Set the list of domains for which to force HTTPS.
-     * @see \SimplePie\Misc::https_url()
-     * Example array('biz', 'example.com', 'example.org', 'www.example.net');
-     */
-    public function set_https_domains($domains)
-    {
-        $this->https_domains = [];
-        foreach ($domains as $domain) {
-            $domain = trim($domain, ". \t\n\r\0\x0B");
-            $segments = array_reverse(explode('.', $domain));
-            $node =& $this->https_domains;
-            foreach ($segments as $segment) {//Build a tree
-                if ($node === true) {
-                    break;
-                }
-                if (!isset($node[$segment])) {
-                    $node[$segment] = [];
-                }
-                $node =& $node[$segment];
-            }
-            $node = true;
-        }
-    }
-
-    /**
-     * Check if the domain is in the list of forced HTTPS.
-     */
-    protected function is_https_domain($domain)
-    {
-        $domain = trim($domain, '. ');
-        $segments = array_reverse(explode('.', $domain));
-        $node =& $this->https_domains;
-        foreach ($segments as $segment) {//Explore the tree
-            if (isset($node[$segment])) {
-                $node =& $node[$segment];
-            } else {
-                break;
-            }
-        }
-        return $node === true;
-    }
-
-    /**
-     * Force HTTPS for selected Web sites.
-     */
-    public function https_url($url)
-    {
-        return (strtolower(substr($url, 0, 7)) === 'http://') &&
-            $this->is_https_domain(parse_url($url, PHP_URL_HOST)) ?
-            substr_replace($url, 's', 4, 0) : //Add the 's' to HTTPS
-            $url;
-    }
-
-    public function sanitize($data, $type, $base = '')
-    {
-        $data = trim($data);
-        if ($data !== '' || $type & \SimplePie\SimplePie::CONSTRUCT_IRI) {
-            if ($type & \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML) {
-                if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . \SimplePie\SimplePie::PCRE_HTML_ATTRIBUTE . '>)/', $data)) {
-                    $type |= \SimplePie\SimplePie::CONSTRUCT_HTML;
-                } else {
-                    $type |= \SimplePie\SimplePie::CONSTRUCT_TEXT;
-                }
-            }
-
-            if ($type & \SimplePie\SimplePie::CONSTRUCT_BASE64) {
-                $data = base64_decode($data);
-            }
-
-            if ($type & (\SimplePie\SimplePie::CONSTRUCT_HTML | \SimplePie\SimplePie::CONSTRUCT_XHTML)) {
-                if (!class_exists('DOMDocument')) {
-                    throw new \SimplePie\Exception('DOMDocument not found, unable to use sanitizer');
-                }
-                $document = new \DOMDocument();
-                $document->encoding = 'UTF-8';
-
-                $data = $this->preprocess($data, $type);
-
-                set_error_handler(['SimplePie\Misc', 'silence_errors']);
-                $document->loadHTML($data);
-                restore_error_handler();
-
-                $xpath = new \DOMXPath($document);
-
-                // Strip comments
-                if ($this->strip_comments) {
-                    $comments = $xpath->query('//comment()');
-
-                    foreach ($comments as $comment) {
-                        $comment->parentNode->removeChild($comment);
-                    }
-                }
-
-                // Strip out HTML tags and attributes that might cause various security problems.
-                // Based on recommendations by Mark Pilgrim at:
-                // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
-                if ($this->strip_htmltags) {
-                    foreach ($this->strip_htmltags as $tag) {
-                        $this->strip_tag($tag, $document, $xpath, $type);
-                    }
-                }
-
-                if ($this->rename_attributes) {
-                    foreach ($this->rename_attributes as $attrib) {
-                        $this->rename_attr($attrib, $xpath);
-                    }
-                }
-
-                if ($this->strip_attributes) {
-                    foreach ($this->strip_attributes as $attrib) {
-                        $this->strip_attr($attrib, $xpath);
-                    }
-                }
-
-                if ($this->add_attributes) {
-                    foreach ($this->add_attributes as $tag => $valuePairs) {
-                        $this->add_attr($tag, $valuePairs, $document);
-                    }
-                }
-
-                // Replace relative URLs
-                $this->base = $base;
-                foreach ($this->replace_url_attributes as $element => $attributes) {
-                    $this->replace_urls($document, $element, $attributes);
-                }
-
-                // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
-                if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache) {
-                    $images = $document->getElementsByTagName('img');
-
-                    foreach ($images as $img) {
-                        if ($img->hasAttribute('src')) {
-                            $image_url = $this->cache_namefilter->filter($img->getAttribute('src'));
-                            $cache = $this->get_cache($image_url);
-
-                            if ($cache->get_data($image_url, false)) {
-                                $img->setAttribute('src', $this->image_handler . $image_url);
-                            } else {
-                                $file = $this->registry->create(File::class, [$img->getAttribute('src'), $this->timeout, 5, ['X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']], $this->useragent, $this->force_fsockopen]);
-                                $headers = $file->headers;
-
-                                if ($file->success && ($file->method & \SimplePie\SimplePie::FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) {
-                                    if ($cache->set_data($image_url, ['headers' => $file->headers, 'body' => $file->body], $this->cache_duration)) {
-                                        $img->setAttribute('src', $this->image_handler . $image_url);
-                                    } else {
-                                        trigger_error("$this->cache_location is not writable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-
-                // Get content node
-                $div = $document->getElementsByTagName('body')->item(0)->firstChild;
-                // Finally, convert to a HTML string
-                $data = trim($document->saveHTML($div));
-
-                if ($this->remove_div) {
-                    $data = preg_replace('/^<div' . \SimplePie\SimplePie::PCRE_XML_ATTRIBUTE . '>/', '', $data);
-                    $data = preg_replace('/<\/div>$/', '', $data);
-                } else {
-                    $data = preg_replace('/^<div' . \SimplePie\SimplePie::PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
-                }
-
-                $data = str_replace('</source>', '', $data);
-            }
-
-            if ($type & \SimplePie\SimplePie::CONSTRUCT_IRI) {
-                $absolute = $this->registry->call(Misc::class, 'absolutize_url', [$data, $base]);
-                if ($absolute !== false) {
-                    $data = $absolute;
-                }
-            }
-
-            if ($type & (\SimplePie\SimplePie::CONSTRUCT_TEXT | \SimplePie\SimplePie::CONSTRUCT_IRI)) {
-                $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
-            }
-
-            if ($this->output_encoding !== 'UTF-8') {
-                $data = $this->registry->call(Misc::class, 'change_encoding', [$data, 'UTF-8', $this->output_encoding]);
-            }
-        }
-        return $data;
-    }
-
-    protected function preprocess($html, $type)
-    {
-        $ret = '';
-        $html = preg_replace('%</?(?:html|body)[^>]*?'.'>%is', '', $html);
-        if ($type & ~\SimplePie\SimplePie::CONSTRUCT_XHTML) {
-            // Atom XHTML constructs are wrapped with a div by default
-            // Note: No protection if $html contains a stray </div>!
-            $html = '<div>' . $html . '</div>';
-            $ret .= '<!DOCTYPE html>';
-            $content_type = 'text/html';
-        } else {
-            $ret .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
-            $content_type = 'application/xhtml+xml';
-        }
-
-        $ret .= '<html><head>';
-        $ret .= '<meta http-equiv="Content-Type" content="' . $content_type . '; charset=utf-8" />';
-        $ret .= '</head><body>' . $html . '</body></html>';
-        return $ret;
-    }
-
-    public function replace_urls($document, $tag, $attributes)
-    {
-        if (!is_array($attributes)) {
-            $attributes = [$attributes];
-        }
-
-        if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags)) {
-            $elements = $document->getElementsByTagName($tag);
-            foreach ($elements as $element) {
-                foreach ($attributes as $attribute) {
-                    if ($element->hasAttribute($attribute)) {
-                        $value = $this->registry->call(Misc::class, 'absolutize_url', [$element->getAttribute($attribute), $this->base]);
-                        if ($value !== false) {
-                            $value = $this->https_url($value);
-                            $element->setAttribute($attribute, $value);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public function do_strip_htmltags($match)
-    {
-        if ($this->encode_instead_of_strip) {
-            if (isset($match[4]) && !in_array(strtolower($match[1]), ['script', 'style'])) {
-                $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
-                $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
-                return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
-            } else {
-                return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
-            }
-        } elseif (isset($match[4]) && !in_array(strtolower($match[1]), ['script', 'style'])) {
-            return $match[4];
-        } else {
-            return '';
-        }
-    }
-
-    protected function strip_tag($tag, $document, $xpath, $type)
-    {
-        $elements = $xpath->query('body//' . $tag);
-        if ($this->encode_instead_of_strip) {
-            foreach ($elements as $element) {
-                $fragment = $document->createDocumentFragment();
-
-                // For elements which aren't script or style, include the tag itself
-                if (!in_array($tag, ['script', 'style'])) {
-                    $text = '<' . $tag;
-                    if ($element->hasAttributes()) {
-                        $attrs = [];
-                        foreach ($element->attributes as $name => $attr) {
-                            $value = $attr->value;
-
-                            // In XHTML, empty values should never exist, so we repeat the value
-                            if (empty($value) && ($type & \SimplePie\SimplePie::CONSTRUCT_XHTML)) {
-                                $value = $name;
-                            }
-                            // For HTML, empty is fine
-                            elseif (empty($value) && ($type & \SimplePie\SimplePie::CONSTRUCT_HTML)) {
-                                $attrs[] = $name;
-                                continue;
-                            }
-
-                            // Standard attribute text
-                            $attrs[] = $name . '="' . $attr->value . '"';
-                        }
-                        $text .= ' ' . implode(' ', $attrs);
-                    }
-                    $text .= '>';
-                    $fragment->appendChild(new \DOMText($text));
-                }
-
-                $number = $element->childNodes->length;
-                for ($i = $number; $i > 0; $i--) {
-                    $child = $element->childNodes->item(0);
-                    $fragment->appendChild($child);
-                }
-
-                if (!in_array($tag, ['script', 'style'])) {
-                    $fragment->appendChild(new \DOMText('</' . $tag . '>'));
-                }
-
-                $element->parentNode->replaceChild($fragment, $element);
-            }
-
-            return;
-        } elseif (in_array($tag, ['script', 'style'])) {
-            foreach ($elements as $element) {
-                $element->parentNode->removeChild($element);
-            }
-
-            return;
-        } else {
-            foreach ($elements as $element) {
-                $fragment = $document->createDocumentFragment();
-                $number = $element->childNodes->length;
-                for ($i = $number; $i > 0; $i--) {
-                    $child = $element->childNodes->item(0);
-                    $fragment->appendChild($child);
-                }
-
-                $element->parentNode->replaceChild($fragment, $element);
-            }
-        }
-    }
-
-    protected function strip_attr($attrib, $xpath)
-    {
-        $elements = $xpath->query('//*[@' . $attrib . ']');
-
-        foreach ($elements as $element) {
-            $element->removeAttribute($attrib);
-        }
-    }
-
-    protected function rename_attr($attrib, $xpath)
-    {
-        $elements = $xpath->query('//*[@' . $attrib . ']');
-
-        foreach ($elements as $element) {
-            $element->setAttribute('data-sanitized-' . $attrib, $element->getAttribute($attrib));
-            $element->removeAttribute($attrib);
-        }
-    }
-
-    protected function add_attr($tag, $valuePairs, $document)
-    {
-        $elements = $document->getElementsByTagName($tag);
-        foreach ($elements as $element) {
-            foreach ($valuePairs as $attrib => $value) {
-                $element->setAttribute($attrib, $value);
-            }
-        }
-    }
-
-    /**
-     * Get a DataCache
-     *
-     * @param string $image_url Only needed for BC, can be removed in SimplePie 2.0.0
-     *
-     * @return DataCache
-     */
-    private function get_cache($image_url = '')
-    {
-        if ($this->cache === null) {
-            // @trigger_error(sprintf('Not providing as PSR-16 cache implementation is deprecated since SimplePie 1.8.0, please use "SimplePie\SimplePie::set_cache()".'), \E_USER_DEPRECATED);
-            $cache = $this->registry->call(Cache::class, 'get_handler', [
-                $this->cache_location,
-                $image_url,
-                Base::TYPE_IMAGE
-            ]);
-
-            return new BaseDataCache($cache);
-        }
-
-        return $this->cache;
-    }
-}
-
-class_alias('SimplePie\Sanitize', 'SimplePie_Sanitize');
-
-}
-
-namespace SimplePie {
-
-/**
- * Handles `<atom:source>`
- *
- * Used by {@see \SimplePie\Item::get_source()}
- *
- * This class can be overloaded with {@see \SimplePie::set_source_class()}
- *
- * @package SimplePie
- * @subpackage API
- */
-class Source implements RegistryAware
-{
-    public $item;
-    public $data = [];
-    protected $registry;
-
-    public function __construct($item, $data)
-    {
-        $this->item = $item;
-        $this->data = $data;
-    }
-
-    public function set_registry(\SimplePie\Registry $registry)/* : void */
-    {
-        $this->registry = $registry;
-    }
-
-    public function __toString()
-    {
-        return md5(serialize($this->data));
-    }
-
-    public function get_source_tags($namespace, $tag)
-    {
-        if (isset($this->data['child'][$namespace][$tag])) {
-            return $this->data['child'][$namespace][$tag];
-        }
-
-        return null;
-    }
-
-    public function get_base($element = [])
-    {
-        return $this->item->get_base($element);
-    }
-
-    public function sanitize($data, $type, $base = '')
-    {
-        return $this->item->sanitize($data, $type, $base);
-    }
-
-    public function get_item()
-    {
-        return $this->item;
-    }
-
-    public function get_title()
-    {
-        if ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'title')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_10_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'title')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_03_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_RSS_10, 'title')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_RSS_090, 'title')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'title')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'title')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'title')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        }
-
-        return null;
-    }
-
-    public function get_category($key = 0)
-    {
-        $categories = $this->get_categories();
-        if (isset($categories[$key])) {
-            return $categories[$key];
-        }
-
-        return null;
-    }
-
-    public function get_categories()
-    {
-        $categories = [];
-
-        foreach ((array) $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'category') as $category) {
-            $term = null;
-            $scheme = null;
-            $label = null;
-            if (isset($category['attribs']['']['term'])) {
-                $term = $this->sanitize($category['attribs']['']['term'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if (isset($category['attribs']['']['scheme'])) {
-                $scheme = $this->sanitize($category['attribs']['']['scheme'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if (isset($category['attribs']['']['label'])) {
-                $label = $this->sanitize($category['attribs']['']['label'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            $categories[] = $this->registry->create(Category::class, [$term, $scheme, $label]);
-        }
-        foreach ((array) $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'category') as $category) {
-            // This is really the label, but keep this as the term also for BC.
-            // Label will also work on retrieving because that falls back to term.
-            $term = $this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            if (isset($category['attribs']['']['domain'])) {
-                $scheme = $this->sanitize($category['attribs']['']['domain'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            } else {
-                $scheme = null;
-            }
-            $categories[] = $this->registry->create(Category::class, [$term, $scheme, null]);
-        }
-        foreach ((array) $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'subject') as $category) {
-            $categories[] = $this->registry->create(Category::class, [$this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null]);
-        }
-        foreach ((array) $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'subject') as $category) {
-            $categories[] = $this->registry->create(Category::class, [$this->sanitize($category['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null]);
-        }
-
-        if (!empty($categories)) {
-            return array_unique($categories);
-        }
-
-        return null;
-    }
-
-    public function get_author($key = 0)
-    {
-        $authors = $this->get_authors();
-        if (isset($authors[$key])) {
-            return $authors[$key];
-        }
-
-        return null;
-    }
-
-    public function get_authors()
-    {
-        $authors = [];
-        foreach ((array) $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'author') as $author) {
-            $name = null;
-            $uri = null;
-            $email = null;
-            if (isset($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['name'][0]['data'])) {
-                $name = $this->sanitize($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['name'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if (isset($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]['data'])) {
-                $uri = $this->sanitize($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]));
-            }
-            if (isset($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['email'][0]['data'])) {
-                $email = $this->sanitize($author['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['email'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if ($name !== null || $email !== null || $uri !== null) {
-                $authors[] = $this->registry->create(Author::class, [$name, $uri, $email]);
-            }
-        }
-        if ($author = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'author')) {
-            $name = null;
-            $url = null;
-            $email = null;
-            if (isset($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['name'][0]['data'])) {
-                $name = $this->sanitize($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['name'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if (isset($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]['data'])) {
-                $url = $this->sanitize($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]));
-            }
-            if (isset($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['email'][0]['data'])) {
-                $email = $this->sanitize($author[0]['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['email'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if ($name !== null || $email !== null || $url !== null) {
-                $authors[] = $this->registry->create(Author::class, [$name, $url, $email]);
-            }
-        }
-        foreach ((array) $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'creator') as $author) {
-            $authors[] = $this->registry->create(Author::class, [$this->sanitize($author['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null]);
-        }
-        foreach ((array) $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'creator') as $author) {
-            $authors[] = $this->registry->create(Author::class, [$this->sanitize($author['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null]);
-        }
-        foreach ((array) $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'author') as $author) {
-            $authors[] = $this->registry->create(Author::class, [$this->sanitize($author['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT), null, null]);
-        }
-
-        if (!empty($authors)) {
-            return array_unique($authors);
-        }
-
-        return null;
-    }
-
-    public function get_contributor($key = 0)
-    {
-        $contributors = $this->get_contributors();
-        if (isset($contributors[$key])) {
-            return $contributors[$key];
-        }
-
-        return null;
-    }
-
-    public function get_contributors()
-    {
-        $contributors = [];
-        foreach ((array) $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'contributor') as $contributor) {
-            $name = null;
-            $uri = null;
-            $email = null;
-            if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['name'][0]['data'])) {
-                $name = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['name'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]['data'])) {
-                $uri = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['uri'][0]));
-            }
-            if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['email'][0]['data'])) {
-                $email = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_10]['email'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if ($name !== null || $email !== null || $uri !== null) {
-                $contributors[] = $this->registry->create(Author::class, [$name, $uri, $email]);
-            }
-        }
-        foreach ((array) $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'contributor') as $contributor) {
-            $name = null;
-            $url = null;
-            $email = null;
-            if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['name'][0]['data'])) {
-                $name = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['name'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]['data'])) {
-                $url = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['url'][0]));
-            }
-            if (isset($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['email'][0]['data'])) {
-                $email = $this->sanitize($contributor['child'][\SimplePie\SimplePie::NAMESPACE_ATOM_03]['email'][0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-            }
-            if ($name !== null || $email !== null || $url !== null) {
-                $contributors[] = $this->registry->create(Author::class, [$name, $url, $email]);
-            }
-        }
-
-        if (!empty($contributors)) {
-            return array_unique($contributors);
-        }
-
-        return null;
-    }
-
-    public function get_link($key = 0, $rel = 'alternate')
-    {
-        $links = $this->get_links($rel);
-        if (isset($links[$key])) {
-            return $links[$key];
-        }
-
-        return null;
-    }
-
-    /**
-     * Added for parity between the parent-level and the item/entry-level.
-     */
-    public function get_permalink()
-    {
-        return $this->get_link(0);
-    }
-
-    public function get_links($rel = 'alternate')
-    {
-        if (!isset($this->data['links'])) {
-            $this->data['links'] = [];
-            if ($links = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'link')) {
-                foreach ($links as $link) {
-                    if (isset($link['attribs']['']['href'])) {
-                        $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
-                        $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($link));
-                    }
-                }
-            }
-            if ($links = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'link')) {
-                foreach ($links as $link) {
-                    if (isset($link['attribs']['']['href'])) {
-                        $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
-                        $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($link));
-                    }
-                }
-            }
-            if ($links = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_RSS_10, 'link')) {
-                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($links[0]));
-            }
-            if ($links = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_RSS_090, 'link')) {
-                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($links[0]));
-            }
-            if ($links = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'link')) {
-                $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($links[0]));
-            }
-
-            $keys = array_keys($this->data['links']);
-            foreach ($keys as $key) {
-                if ($this->registry->call(Misc::class, 'is_isegment_nz_nc', [$key])) {
-                    if (isset($this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key])) {
-                        $this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key]);
-                        $this->data['links'][$key] =& $this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key];
-                    } else {
-                        $this->data['links'][\SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
-                    }
-                } elseif (substr($key, 0, 41) === \SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY) {
-                    $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
-                }
-                $this->data['links'][$key] = array_unique($this->data['links'][$key]);
-            }
-        }
-
-        if (isset($this->data['links'][$rel])) {
-            return $this->data['links'][$rel];
-        }
-
-        return null;
-    }
-
-    public function get_description()
-    {
-        if ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'subtitle')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_10_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'tagline')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_03_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_RSS_10, 'description')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_RSS_090, 'description')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'description')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'description')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'description')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'summary')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_HTML, $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'subtitle')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_HTML, $this->get_base($return[0]));
-        }
-
-        return null;
-    }
-
-    public function get_copyright()
-    {
-        if ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'rights')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_10_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_03, 'copyright')) {
-            return $this->sanitize($return[0]['data'], $this->registry->call(Misc::class, 'atom_03_construct_type', [$return[0]['attribs']]), $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'copyright')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'rights')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'rights')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        }
-
-        return null;
-    }
-
-    public function get_language()
-    {
-        if ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_RSS_20, 'language')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_DC_11, 'language')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_DC_10, 'language')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        } elseif (isset($this->data['xml_lang'])) {
-            return $this->sanitize($this->data['xml_lang'], \SimplePie\SimplePie::CONSTRUCT_TEXT);
-        }
-
-        return null;
-    }
-
-    public function get_latitude()
-    {
-        if ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_W3C_BASIC_GEO, 'lat')) {
-            return (float) $return[0]['data'];
-        } elseif (($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) {
-            return (float) $match[1];
-        }
-
-        return null;
-    }
-
-    public function get_longitude()
-    {
-        if ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_W3C_BASIC_GEO, 'long')) {
-            return (float) $return[0]['data'];
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_W3C_BASIC_GEO, 'lon')) {
-            return (float) $return[0]['data'];
-        } elseif (($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) {
-            return (float) $match[2];
-        }
-
-        return null;
-    }
-
-    public function get_image_url()
-    {
-        if ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ITUNES, 'image')) {
-            return $this->sanitize($return[0]['attribs']['']['href'], \SimplePie\SimplePie::CONSTRUCT_IRI);
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'logo')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($return[0]));
-        } elseif ($return = $this->get_source_tags(\SimplePie\SimplePie::NAMESPACE_ATOM_10, 'icon')) {
-            return $this->sanitize($return[0]['data'], \SimplePie\SimplePie::CONSTRUCT_IRI, $this->get_base($return[0]));
-        }
-
-        return null;
-    }
-}
-
-class_alias('SimplePie\Source', 'SimplePie_Source');
-
-}
-
-namespace SimplePie\XML\Declaration {
-
-/**
- * Parses the XML Declaration
- *
- * @package SimplePie
- * @subpackage Parsing
- */
-class Parser
-{
-    /**
-     * XML Version
-     *
-     * @access public
-     * @var string
-     */
-    public $version = '1.0';
-
-    /**
-     * Encoding
-     *
-     * @access public
-     * @var string
-     */
-    public $encoding = 'UTF-8';
-
-    /**
-     * Standalone
-     *
-     * @access public
-     * @var bool
-     */
-    public $standalone = false;
-
-    private const STATE_BEFORE_VERSION_NAME = 'before_version_name';
-
-    private const STATE_VERSION_NAME = 'version_name';
-
-    private const STATE_VERSION_EQUALS = 'version_equals';
-
-    private const STATE_VERSION_VALUE = 'version_value';
-
-    private const STATE_ENCODING_NAME = 'encoding_name';
-
-    private const STATE_EMIT = 'emit';
-
-    private const STATE_ENCODING_EQUALS = 'encoding_equals';
-
-    private const STATE_STANDALONE_NAME = 'standalone_name';
-
-    private const STATE_ENCODING_VALUE = 'encoding_value';
-
-    private const STATE_STANDALONE_EQUALS = 'standalone_equals';
-
-    private const STATE_STANDALONE_VALUE = 'standalone_value';
-
-    private const STATE_ERROR = false;
-
-    /**
-     * Current state of the state machine
-     *
-     * @access private
-     * @var self::STATE_*
-     */
-    public $state = self::STATE_BEFORE_VERSION_NAME;
-
-    /**
-     * Input data
-     *
-     * @access private
-     * @var string
-     */
-    public $data = '';
-
-    /**
-     * Input data length (to avoid calling strlen() everytime this is needed)
-     *
-     * @access private
-     * @var int
-     */
-    public $data_length = 0;
-
-    /**
-     * Current position of the pointer
-     *
-     * @var int
-     * @access private
-     */
-    public $position = 0;
-
-    /**
-     * Create an instance of the class with the input data
-     *
-     * @access public
-     * @param string $data Input data
-     */
-    public function __construct($data)
-    {
-        $this->data = $data;
-        $this->data_length = strlen($this->data);
-    }
-
-    /**
-     * Parse the input data
-     *
-     * @access public
-     * @return bool true on success, false on failure
-     */
-    public function parse()
-    {
-        while ($this->state && $this->state !== self::STATE_EMIT && $this->has_data()) {
-            $state = $this->state;
-            $this->$state();
-        }
-        $this->data = '';
-        if ($this->state === self::STATE_EMIT) {
-            return true;
-        }
-
-        $this->version = '';
-        $this->encoding = '';
-        $this->standalone = '';
-        return false;
-    }
-
-    /**
-     * Check whether there is data beyond the pointer
-     *
-     * @access private
-     * @return bool true if there is further data, false if not
-     */
-    public function has_data()
-    {
-        return (bool) ($this->position < $this->data_length);
-    }
-
-    /**
-     * Advance past any whitespace
-     *
-     * @return int Number of whitespace characters passed
-     */
-    public function skip_whitespace()
-    {
-        $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
-        $this->position += $whitespace;
-        return $whitespace;
-    }
-
-    /**
-     * Read value
-     */
-    public function get_value()
-    {
-        $quote = substr($this->data, $this->position, 1);
-        if ($quote === '"' || $quote === "'") {
-            $this->position++;
-            $len = strcspn($this->data, $quote, $this->position);
-            if ($this->has_data()) {
-                $value = substr($this->data, $this->position, $len);
-                $this->position += $len + 1;
-                return $value;
-            }
-        }
-        return false;
-    }
-
-    public function before_version_name()
-    {
-        if ($this->skip_whitespace()) {
-            $this->state = self::STATE_VERSION_NAME;
-        } else {
-            $this->state = self::STATE_ERROR;
-        }
-    }
-
-    public function version_name()
-    {
-        if (substr($this->data, $this->position, 7) === 'version') {
-            $this->position += 7;
-            $this->skip_whitespace();
-            $this->state = self::STATE_VERSION_EQUALS;
-        } else {
-            $this->state = self::STATE_ERROR;
-        }
-    }
-
-    public function version_equals()
-    {
-        if (substr($this->data, $this->position, 1) === '=') {
-            $this->position++;
-            $this->skip_whitespace();
-            $this->state = self::STATE_VERSION_VALUE;
-        } else {
-            $this->state = self::STATE_ERROR;
-        }
-    }
-
-    public function version_value()
-    {
-        if ($this->version = $this->get_value()) {
-            $this->skip_whitespace();
-            if ($this->has_data()) {
-                $this->state = self::STATE_ENCODING_NAME;
-            } else {
-                $this->state = self::STATE_EMIT;
-            }
-        } else {
-            $this->state = self::STATE_ERROR;
-        }
-    }
-
-    public function encoding_name()
-    {
-        if (substr($this->data, $this->position, 8) === 'encoding') {
-            $this->position += 8;
-            $this->skip_whitespace();
-            $this->state = self::STATE_ENCODING_EQUALS;
-        } else {
-            $this->state = self::STATE_STANDALONE_NAME;
-        }
-    }
-
-    public function encoding_equals()
-    {
-        if (substr($this->data, $this->position, 1) === '=') {
-            $this->position++;
-            $this->skip_whitespace();
-            $this->state = self::STATE_ENCODING_VALUE;
-        } else {
-            $this->state = self::STATE_ERROR;
-        }
-    }
-
-    public function encoding_value()
-    {
-        if ($this->encoding = $this->get_value()) {
-            $this->skip_whitespace();
-            if ($this->has_data()) {
-                $this->state = self::STATE_STANDALONE_NAME;
-            } else {
-                $this->state = self::STATE_EMIT;
-            }
-        } else {
-            $this->state = self::STATE_ERROR;
-        }
-    }
-
-    public function standalone_name()
-    {
-        if (substr($this->data, $this->position, 10) === 'standalone') {
-            $this->position += 10;
-            $this->skip_whitespace();
-            $this->state = self::STATE_STANDALONE_EQUALS;
-        } else {
-            $this->state = self::STATE_ERROR;
-        }
-    }
-
-    public function standalone_equals()
-    {
-        if (substr($this->data, $this->position, 1) === '=') {
-            $this->position++;
-            $this->skip_whitespace();
-            $this->state = self::STATE_STANDALONE_VALUE;
-        } else {
-            $this->state = self::STATE_ERROR;
-        }
-    }
-
-    public function standalone_value()
-    {
-        if ($standalone = $this->get_value()) {
-            switch ($standalone) {
-                case 'yes':
-                    $this->standalone = true;
-                    break;
-
-                case 'no':
-                    $this->standalone = false;
-                    break;
-
-                default:
-                    $this->state = self::STATE_ERROR;
-                    return;
-            }
-
-            $this->skip_whitespace();
-            if ($this->has_data()) {
-                $this->state = self::STATE_ERROR;
-            } else {
-                $this->state = self::STATE_EMIT;
-            }
-        } else {
-            $this->state = self::STATE_ERROR;
-        }
-    }
-}
-
-class_alias('SimplePie\XML\Declaration\Parser', 'SimplePie_XML_Declaration_Parser');
-
-}
-
-namespace {
-
-use SimplePie\Misc;
-
-class_exists('SimplePie\Misc');
-
-// @trigger_error(sprintf('Using the "SimplePie_Misc" class is deprecated since SimplePie 1.7.0, use "SimplePie\Misc" instead.'), \E_USER_DEPRECATED);
-
-if (\false) {
-    /** @deprecated since SimplePie 1.7.0, use "SimplePie\Misc" instead */
-    class SimplePie_Misc extends Misc
-    {
-    }
-}
-
-}
-
-namespace {
-
-/**
- * SimplePie class.
- *
- * Class for backward compatibility.
- *
- * @deprecated Use {@see SimplePie} directly
- * @package SimplePie
- * @subpackage API
- */
-class SimplePie_Core extends SimplePie
-{
-}
-
-}
-
-namespace {
-
-/**
- * Decode HTML Entities
- *
- * This implements HTML5 as of revision 967 (2007-06-28)
- *
- * @deprecated Use DOMDocument instead!
- * @package SimplePie
- */
-class SimplePie_Decode_HTML_Entities
-{
-    /**
-     * Data to be parsed
-     *
-     * @access private
-     * @var string
-     */
-    public $data = '';
-
-    /**
-     * Currently consumed bytes
-     *
-     * @access private
-     * @var string
-     */
-    public $consumed = '';
-
-    /**
-     * Position of the current byte being parsed
-     *
-     * @access private
-     * @var int
-     */
-    public $position = 0;
-
-    /**
-     * Create an instance of the class with the input data
-     *
-     * @access public
-     * @param string $data Input data
-     */
-    public function __construct($data)
-    {
-        $this->data = $data;
-    }
-
-    /**
-     * Parse the input data
-     *
-     * @access public
-     * @return string Output data
-     */
-    public function parse()
-    {
-        while (($this->position = strpos($this->data, '&', $this->position)) !== false) {
-            $this->consume();
-            $this->entity();
-            $this->consumed = '';
-        }
-        return $this->data;
-    }
-
-    /**
-     * Consume the next byte
-     *
-     * @access private
-     * @return mixed The next byte, or false, if there is no more data
-     */
-    public function consume()
-    {
-        if (isset($this->data[$this->position])) {
-            $this->consumed .= $this->data[$this->position];
-            return $this->data[$this->position++];
-        }
-
-        return false;
-    }
-
-    /**
-     * Consume a range of characters
-     *
-     * @access private
-     * @param string $chars Characters to consume
-     * @return mixed A series of characters that match the range, or false
-     */
-    public function consume_range($chars)
-    {
-        if ($len = strspn($this->data, $chars, $this->position)) {
-            $data = substr($this->data, $this->position, $len);
-            $this->consumed .= $data;
-            $this->position += $len;
-            return $data;
-        }
-
-        return false;
-    }
-
-    /**
-     * Unconsume one byte
-     *
-     * @access private
-     */
-    public function unconsume()
-    {
-        $this->consumed = substr($this->consumed, 0, -1);
-        $this->position--;
-    }
-
-    /**
-     * Decode an entity
-     *
-     * @access private
-     */
-    public function entity()
-    {
-        switch ($this->consume()) {
-            case "\x09":
-            case "\x0A":
-            case "\x0B":
-            case "\x0C":
-            case "\x20":
-            case "\x3C":
-            case "\x26":
-            case false:
-                break;
-
-            case "\x23":
-                switch ($this->consume()) {
-                    case "\x78":
-                    case "\x58":
-                        $range = '0123456789ABCDEFabcdef';
-                        $hex = true;
-                        break;
-
-                    default:
-                        $range = '0123456789';
-                        $hex = false;
-                        $this->unconsume();
-                        break;
-                }
-
-                if ($codepoint = $this->consume_range($range)) {
-                    static $windows_1252_specials = [0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8"];
-
-                    if ($hex) {
-                        $codepoint = hexdec($codepoint);
-                    } else {
-                        $codepoint = intval($codepoint);
-                    }
-
-                    if (isset($windows_1252_specials[$codepoint])) {
-                        $replacement = $windows_1252_specials[$codepoint];
-                    } else {
-                        $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
-                    }
-
-                    if (!in_array($this->consume(), [';', false], true)) {
-                        $this->unconsume();
-                    }
-
-                    $consumed_length = strlen($this->consumed);
-                    $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
-                    $this->position += strlen($replacement) - $consumed_length;
-                }
-                break;
-
-            default:
-                static $entities = [
-                    'Aacute' => "\xC3\x81",
-                    'aacute' => "\xC3\xA1",
-                    'Aacute;' => "\xC3\x81",
-                    'aacute;' => "\xC3\xA1",
-                    'Acirc' => "\xC3\x82",
-                    'acirc' => "\xC3\xA2",
-                    'Acirc;' => "\xC3\x82",
-                    'acirc;' => "\xC3\xA2",
-                    'acute' => "\xC2\xB4",
-                    'acute;' => "\xC2\xB4",
-                    'AElig' => "\xC3\x86",
-                    'aelig' => "\xC3\xA6",
-                    'AElig;' => "\xC3\x86",
-                    'aelig;' => "\xC3\xA6",
-                    'Agrave' => "\xC3\x80",
-                    'agrave' => "\xC3\xA0",
-                    'Agrave;' => "\xC3\x80",
-                    'agrave;' => "\xC3\xA0",
-                    'alefsym;' => "\xE2\x84\xB5",
-                    'Alpha;' => "\xCE\x91",
-                    'alpha;' => "\xCE\xB1",
-                    'AMP' => "\x26",
-                    'amp' => "\x26",
-                    'AMP;' => "\x26",
-                    'amp;' => "\x26",
-                    'and;' => "\xE2\x88\xA7",
-                    'ang;' => "\xE2\x88\xA0",
-                    'apos;' => "\x27",
-                    'Aring' => "\xC3\x85",
-                    'aring' => "\xC3\xA5",
-                    'Aring;' => "\xC3\x85",
-                    'aring;' => "\xC3\xA5",
-                    'asymp;' => "\xE2\x89\x88",
-                    'Atilde' => "\xC3\x83",
-                    'atilde' => "\xC3\xA3",
-                    'Atilde;' => "\xC3\x83",
-                    'atilde;' => "\xC3\xA3",
-                    'Auml' => "\xC3\x84",
-                    'auml' => "\xC3\xA4",
-                    'Auml;' => "\xC3\x84",
-                    'auml;' => "\xC3\xA4",
-                    'bdquo;' => "\xE2\x80\x9E",
-                    'Beta;' => "\xCE\x92",
-                    'beta;' => "\xCE\xB2",
-                    'brvbar' => "\xC2\xA6",
-                    'brvbar;' => "\xC2\xA6",
-                    'bull;' => "\xE2\x80\xA2",
-                    'cap;' => "\xE2\x88\xA9",
-                    'Ccedil' => "\xC3\x87",
-                    'ccedil' => "\xC3\xA7",
-                    'Ccedil;' => "\xC3\x87",
-                    'ccedil;' => "\xC3\xA7",
-                    'cedil' => "\xC2\xB8",
-                    'cedil;' => "\xC2\xB8",
-                    'cent' => "\xC2\xA2",
-                    'cent;' => "\xC2\xA2",
-                    'Chi;' => "\xCE\xA7",
-                    'chi;' => "\xCF\x87",
-                    'circ;' => "\xCB\x86",
-                    'clubs;' => "\xE2\x99\xA3",
-                    'cong;' => "\xE2\x89\x85",
-                    'COPY' => "\xC2\xA9",
-                    'copy' => "\xC2\xA9",
-                    'COPY;' => "\xC2\xA9",
-                    'copy;' => "\xC2\xA9",
-                    'crarr;' => "\xE2\x86\xB5",
-                    'cup;' => "\xE2\x88\xAA",
-                    'curren' => "\xC2\xA4",
-                    'curren;' => "\xC2\xA4",
-                    'Dagger;' => "\xE2\x80\xA1",
-                    'dagger;' => "\xE2\x80\xA0",
-                    'dArr;' => "\xE2\x87\x93",
-                    'darr;' => "\xE2\x86\x93",
-                    'deg' => "\xC2\xB0",
-                    'deg;' => "\xC2\xB0",
-                    'Delta;' => "\xCE\x94",
-                    'delta;' => "\xCE\xB4",
-                    'diams;' => "\xE2\x99\xA6",
-                    'divide' => "\xC3\xB7",
-                    'divide;' => "\xC3\xB7",
-                    'Eacute' => "\xC3\x89",
-                    'eacute' => "\xC3\xA9",
-                    'Eacute;' => "\xC3\x89",
-                    'eacute;' => "\xC3\xA9",
-                    'Ecirc' => "\xC3\x8A",
-                    'ecirc' => "\xC3\xAA",
-                    'Ecirc;' => "\xC3\x8A",
-                    'ecirc;' => "\xC3\xAA",
-                    'Egrave' => "\xC3\x88",
-                    'egrave' => "\xC3\xA8",
-                    'Egrave;' => "\xC3\x88",
-                    'egrave;' => "\xC3\xA8",
-                    'empty;' => "\xE2\x88\x85",
-                    'emsp;' => "\xE2\x80\x83",
-                    'ensp;' => "\xE2\x80\x82",
-                    'Epsilon;' => "\xCE\x95",
-                    'epsilon;' => "\xCE\xB5",
-                    'equiv;' => "\xE2\x89\xA1",
-                    'Eta;' => "\xCE\x97",
-                    'eta;' => "\xCE\xB7",
-                    'ETH' => "\xC3\x90",
-                    'eth' => "\xC3\xB0",
-                    'ETH;' => "\xC3\x90",
-                    'eth;' => "\xC3\xB0",
-                    'Euml' => "\xC3\x8B",
-                    'euml' => "\xC3\xAB",
-                    'Euml;' => "\xC3\x8B",
-                    'euml;' => "\xC3\xAB",
-                    'euro;' => "\xE2\x82\xAC",
-                    'exist;' => "\xE2\x88\x83",
-                    'fnof;' => "\xC6\x92",
-                    'forall;' => "\xE2\x88\x80",
-                    'frac12' => "\xC2\xBD",
-                    'frac12;' => "\xC2\xBD",
-                    'frac14' => "\xC2\xBC",
-                    'frac14;' => "\xC2\xBC",
-                    'frac34' => "\xC2\xBE",
-                    'frac34;' => "\xC2\xBE",
-                    'frasl;' => "\xE2\x81\x84",
-                    'Gamma;' => "\xCE\x93",
-                    'gamma;' => "\xCE\xB3",
-                    'ge;' => "\xE2\x89\xA5",
-                    'GT' => "\x3E",
-                    'gt' => "\x3E",
-                    'GT;' => "\x3E",
-                    'gt;' => "\x3E",
-                    'hArr;' => "\xE2\x87\x94",
-                    'harr;' => "\xE2\x86\x94",
-                    'hearts;' => "\xE2\x99\xA5",
-                    'hellip;' => "\xE2\x80\xA6",
-                    'Iacute' => "\xC3\x8D",
-                    'iacute' => "\xC3\xAD",
-                    'Iacute;' => "\xC3\x8D",
-                    'iacute;' => "\xC3\xAD",
-                    'Icirc' => "\xC3\x8E",
-                    'icirc' => "\xC3\xAE",
-                    'Icirc;' => "\xC3\x8E",
-                    'icirc;' => "\xC3\xAE",
-                    'iexcl' => "\xC2\xA1",
-                    'iexcl;' => "\xC2\xA1",
-                    'Igrave' => "\xC3\x8C",
-                    'igrave' => "\xC3\xAC",
-                    'Igrave;' => "\xC3\x8C",
-                    'igrave;' => "\xC3\xAC",
-                    'image;' => "\xE2\x84\x91",
-                    'infin;' => "\xE2\x88\x9E",
-                    'int;' => "\xE2\x88\xAB",
-                    'Iota;' => "\xCE\x99",
-                    'iota;' => "\xCE\xB9",
-                    'iquest' => "\xC2\xBF",
-                    'iquest;' => "\xC2\xBF",
-                    'isin;' => "\xE2\x88\x88",
-                    'Iuml' => "\xC3\x8F",
-                    'iuml' => "\xC3\xAF",
-                    'Iuml;' => "\xC3\x8F",
-                    'iuml;' => "\xC3\xAF",
-                    'Kappa;' => "\xCE\x9A",
-                    'kappa;' => "\xCE\xBA",
-                    'Lambda;' => "\xCE\x9B",
-                    'lambda;' => "\xCE\xBB",
-                    'lang;' => "\xE3\x80\x88",
-                    'laquo' => "\xC2\xAB",
-                    'laquo;' => "\xC2\xAB",
-                    'lArr;' => "\xE2\x87\x90",
-                    'larr;' => "\xE2\x86\x90",
-                    'lceil;' => "\xE2\x8C\x88",
-                    'ldquo;' => "\xE2\x80\x9C",
-                    'le;' => "\xE2\x89\xA4",
-                    'lfloor;' => "\xE2\x8C\x8A",
-                    'lowast;' => "\xE2\x88\x97",
-                    'loz;' => "\xE2\x97\x8A",
-                    'lrm;' => "\xE2\x80\x8E",
-                    'lsaquo;' => "\xE2\x80\xB9",
-                    'lsquo;' => "\xE2\x80\x98",
-                    'LT' => "\x3C",
-                    'lt' => "\x3C",
-                    'LT;' => "\x3C",
-                    'lt;' => "\x3C",
-                    'macr' => "\xC2\xAF",
-                    'macr;' => "\xC2\xAF",
-                    'mdash;' => "\xE2\x80\x94",
-                    'micro' => "\xC2\xB5",
-                    'micro;' => "\xC2\xB5",
-                    'middot' => "\xC2\xB7",
-                    'middot;' => "\xC2\xB7",
-                    'minus;' => "\xE2\x88\x92",
-                    'Mu;' => "\xCE\x9C",
-                    'mu;' => "\xCE\xBC",
-                    'nabla;' => "\xE2\x88\x87",
-                    'nbsp' => "\xC2\xA0",
-                    'nbsp;' => "\xC2\xA0",
-                    'ndash;' => "\xE2\x80\x93",
-                    'ne;' => "\xE2\x89\xA0",
-                    'ni;' => "\xE2\x88\x8B",
-                    'not' => "\xC2\xAC",
-                    'not;' => "\xC2\xAC",
-                    'notin;' => "\xE2\x88\x89",
-                    'nsub;' => "\xE2\x8A\x84",
-                    'Ntilde' => "\xC3\x91",
-                    'ntilde' => "\xC3\xB1",
-                    'Ntilde;' => "\xC3\x91",
-                    'ntilde;' => "\xC3\xB1",
-                    'Nu;' => "\xCE\x9D",
-                    'nu;' => "\xCE\xBD",
-                    'Oacute' => "\xC3\x93",
-                    'oacute' => "\xC3\xB3",
-                    'Oacute;' => "\xC3\x93",
-                    'oacute;' => "\xC3\xB3",
-                    'Ocirc' => "\xC3\x94",
-                    'ocirc' => "\xC3\xB4",
-                    'Ocirc;' => "\xC3\x94",
-                    'ocirc;' => "\xC3\xB4",
-                    'OElig;' => "\xC5\x92",
-                    'oelig;' => "\xC5\x93",
-                    'Ograve' => "\xC3\x92",
-                    'ograve' => "\xC3\xB2",
-                    'Ograve;' => "\xC3\x92",
-                    'ograve;' => "\xC3\xB2",
-                    'oline;' => "\xE2\x80\xBE",
-                    'Omega;' => "\xCE\xA9",
-                    'omega;' => "\xCF\x89",
-                    'Omicron;' => "\xCE\x9F",
-                    'omicron;' => "\xCE\xBF",
-                    'oplus;' => "\xE2\x8A\x95",
-                    'or;' => "\xE2\x88\xA8",
-                    'ordf' => "\xC2\xAA",
-                    'ordf;' => "\xC2\xAA",
-                    'ordm' => "\xC2\xBA",
-                    'ordm;' => "\xC2\xBA",
-                    'Oslash' => "\xC3\x98",
-                    'oslash' => "\xC3\xB8",
-                    'Oslash;' => "\xC3\x98",
-                    'oslash;' => "\xC3\xB8",
-                    'Otilde' => "\xC3\x95",
-                    'otilde' => "\xC3\xB5",
-                    'Otilde;' => "\xC3\x95",
-                    'otilde;' => "\xC3\xB5",
-                    'otimes;' => "\xE2\x8A\x97",
-                    'Ouml' => "\xC3\x96",
-                    'ouml' => "\xC3\xB6",
-                    'Ouml;' => "\xC3\x96",
-                    'ouml;' => "\xC3\xB6",
-                    'para' => "\xC2\xB6",
-                    'para;' => "\xC2\xB6",
-                    'part;' => "\xE2\x88\x82",
-                    'permil;' => "\xE2\x80\xB0",
-                    'perp;' => "\xE2\x8A\xA5",
-                    'Phi;' => "\xCE\xA6",
-                    'phi;' => "\xCF\x86",
-                    'Pi;' => "\xCE\xA0",
-                    'pi;' => "\xCF\x80",
-                    'piv;' => "\xCF\x96",
-                    'plusmn' => "\xC2\xB1",
-                    'plusmn;' => "\xC2\xB1",
-                    'pound' => "\xC2\xA3",
-                    'pound;' => "\xC2\xA3",
-                    'Prime;' => "\xE2\x80\xB3",
-                    'prime;' => "\xE2\x80\xB2",
-                    'prod;' => "\xE2\x88\x8F",
-                    'prop;' => "\xE2\x88\x9D",
-                    'Psi;' => "\xCE\xA8",
-                    'psi;' => "\xCF\x88",
-                    'QUOT' => "\x22",
-                    'quot' => "\x22",
-                    'QUOT;' => "\x22",
-                    'quot;' => "\x22",
-                    'radic;' => "\xE2\x88\x9A",
-                    'rang;' => "\xE3\x80\x89",
-                    'raquo' => "\xC2\xBB",
-                    'raquo;' => "\xC2\xBB",
-                    'rArr;' => "\xE2\x87\x92",
-                    'rarr;' => "\xE2\x86\x92",
-                    'rceil;' => "\xE2\x8C\x89",
-                    'rdquo;' => "\xE2\x80\x9D",
-                    'real;' => "\xE2\x84\x9C",
-                    'REG' => "\xC2\xAE",
-                    'reg' => "\xC2\xAE",
-                    'REG;' => "\xC2\xAE",
-                    'reg;' => "\xC2\xAE",
-                    'rfloor;' => "\xE2\x8C\x8B",
-                    'Rho;' => "\xCE\xA1",
-                    'rho;' => "\xCF\x81",
-                    'rlm;' => "\xE2\x80\x8F",
-                    'rsaquo;' => "\xE2\x80\xBA",
-                    'rsquo;' => "\xE2\x80\x99",
-                    'sbquo;' => "\xE2\x80\x9A",
-                    'Scaron;' => "\xC5\xA0",
-                    'scaron;' => "\xC5\xA1",
-                    'sdot;' => "\xE2\x8B\x85",
-                    'sect' => "\xC2\xA7",
-                    'sect;' => "\xC2\xA7",
-                    'shy' => "\xC2\xAD",
-                    'shy;' => "\xC2\xAD",
-                    'Sigma;' => "\xCE\xA3",
-                    'sigma;' => "\xCF\x83",
-                    'sigmaf;' => "\xCF\x82",
-                    'sim;' => "\xE2\x88\xBC",
-                    'spades;' => "\xE2\x99\xA0",
-                    'sub;' => "\xE2\x8A\x82",
-                    'sube;' => "\xE2\x8A\x86",
-                    'sum;' => "\xE2\x88\x91",
-                    'sup;' => "\xE2\x8A\x83",
-                    'sup1' => "\xC2\xB9",
-                    'sup1;' => "\xC2\xB9",
-                    'sup2' => "\xC2\xB2",
-                    'sup2;' => "\xC2\xB2",
-                    'sup3' => "\xC2\xB3",
-                    'sup3;' => "\xC2\xB3",
-                    'supe;' => "\xE2\x8A\x87",
-                    'szlig' => "\xC3\x9F",
-                    'szlig;' => "\xC3\x9F",
-                    'Tau;' => "\xCE\xA4",
-                    'tau;' => "\xCF\x84",
-                    'there4;' => "\xE2\x88\xB4",
-                    'Theta;' => "\xCE\x98",
-                    'theta;' => "\xCE\xB8",
-                    'thetasym;' => "\xCF\x91",
-                    'thinsp;' => "\xE2\x80\x89",
-                    'THORN' => "\xC3\x9E",
-                    'thorn' => "\xC3\xBE",
-                    'THORN;' => "\xC3\x9E",
-                    'thorn;' => "\xC3\xBE",
-                    'tilde;' => "\xCB\x9C",
-                    'times' => "\xC3\x97",
-                    'times;' => "\xC3\x97",
-                    'TRADE;' => "\xE2\x84\xA2",
-                    'trade;' => "\xE2\x84\xA2",
-                    'Uacute' => "\xC3\x9A",
-                    'uacute' => "\xC3\xBA",
-                    'Uacute;' => "\xC3\x9A",
-                    'uacute;' => "\xC3\xBA",
-                    'uArr;' => "\xE2\x87\x91",
-                    'uarr;' => "\xE2\x86\x91",
-                    'Ucirc' => "\xC3\x9B",
-                    'ucirc' => "\xC3\xBB",
-                    'Ucirc;' => "\xC3\x9B",
-                    'ucirc;' => "\xC3\xBB",
-                    'Ugrave' => "\xC3\x99",
-                    'ugrave' => "\xC3\xB9",
-                    'Ugrave;' => "\xC3\x99",
-                    'ugrave;' => "\xC3\xB9",
-                    'uml' => "\xC2\xA8",
-                    'uml;' => "\xC2\xA8",
-                    'upsih;' => "\xCF\x92",
-                    'Upsilon;' => "\xCE\xA5",
-                    'upsilon;' => "\xCF\x85",
-                    'Uuml' => "\xC3\x9C",
-                    'uuml' => "\xC3\xBC",
-                    'Uuml;' => "\xC3\x9C",
-                    'uuml;' => "\xC3\xBC",
-                    'weierp;' => "\xE2\x84\x98",
-                    'Xi;' => "\xCE\x9E",
-                    'xi;' => "\xCE\xBE",
-                    'Yacute' => "\xC3\x9D",
-                    'yacute' => "\xC3\xBD",
-                    'Yacute;' => "\xC3\x9D",
-                    'yacute;' => "\xC3\xBD",
-                    'yen' => "\xC2\xA5",
-                    'yen;' => "\xC2\xA5",
-                    'yuml' => "\xC3\xBF",
-                    'Yuml;' => "\xC5\xB8",
-                    'yuml;' => "\xC3\xBF",
-                    'Zeta;' => "\xCE\x96",
-                    'zeta;' => "\xCE\xB6",
-                    'zwj;' => "\xE2\x80\x8D",
-                    'zwnj;' => "\xE2\x80\x8C"
-                ];
-
-                for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++) {
-                    $consumed = substr($this->consumed, 1);
-                    if (isset($entities[$consumed])) {
-                        $match = $consumed;
-                    }
-                }
-
-                if ($match !== null) {
-                    $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
-                    $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
-                }
-                break;
-        }
-    }
-}
-
-}
-
-namespace {
-
-use SimplePie\SimplePie as NamespacedSimplePie;
-
-class_exists('SimplePie\SimplePie');
-
-// @trigger_error(sprintf('Using the "SimplePie" class is deprecated since SimplePie 1.7.0, use "SimplePie\SimplePie" instead.'), \E_USER_DEPRECATED);
-
-if (\false) {
-    /** @deprecated since SimplePie 1.7.0, use "SimplePie\SimplePie" instead */
-    class SimplePie extends NamespacedSimplePie
-    {
-    }
-}
-
-/**
- * SimplePie Name
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAME instead.
- */
-define('SIMPLEPIE_NAME', NamespacedSimplePie::NAME);
-
-/**
- * SimplePie Version
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::VERSION instead.
- */
-define('SIMPLEPIE_VERSION', NamespacedSimplePie::VERSION);
-
-/**
- * SimplePie Build
- * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::get_build() only every load of simplepie.inc)
- * @deprecated since SimplePie 1.7.0, use \SimplePie\Misc::get_build() instead.
- */
-define('SIMPLEPIE_BUILD', '20230120083904');
-
-/**
- * SimplePie Website URL
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::URL instead.
- */
-define('SIMPLEPIE_URL', NamespacedSimplePie::URL);
-
-/**
- * SimplePie Useragent
- * @see SimplePie::set_useragent()
- * @deprecated since SimplePie 1.7.0, use \SimplePie\Misc::get_default_useragent() instead.
- */
-define('SIMPLEPIE_USERAGENT', \SimplePie\Misc::get_default_useragent());
-
-/**
- * SimplePie Linkback
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::LINKBACK instead.
- */
-define('SIMPLEPIE_LINKBACK', NamespacedSimplePie::LINKBACK);
-
-/**
- * No Autodiscovery
- * @see SimplePie::set_autodiscovery_level()
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::LOCATOR_NONE instead.
- */
-define('SIMPLEPIE_LOCATOR_NONE', NamespacedSimplePie::LOCATOR_NONE);
-
-/**
- * Feed Link Element Autodiscovery
- * @see SimplePie::set_autodiscovery_level()
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::LOCATOR_AUTODISCOVERY instead.
- */
-define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', NamespacedSimplePie::LOCATOR_AUTODISCOVERY);
-
-/**
- * Local Feed Extension Autodiscovery
- * @see SimplePie::set_autodiscovery_level()
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::LOCATOR_LOCAL_EXTENSION instead.
- */
-define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', NamespacedSimplePie::LOCATOR_LOCAL_EXTENSION);
-
-/**
- * Local Feed Body Autodiscovery
- * @see SimplePie::set_autodiscovery_level()
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::LOCATOR_LOCAL_BODY instead.
- */
-define('SIMPLEPIE_LOCATOR_LOCAL_BODY', NamespacedSimplePie::LOCATOR_LOCAL_BODY);
-
-/**
- * Remote Feed Extension Autodiscovery
- * @see SimplePie::set_autodiscovery_level()
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::LOCATOR_REMOTE_EXTENSION instead.
- */
-define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', NamespacedSimplePie::LOCATOR_REMOTE_EXTENSION);
-
-/**
- * Remote Feed Body Autodiscovery
- * @see SimplePie::set_autodiscovery_level()
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::LOCATOR_REMOTE_BODY instead.
- */
-define('SIMPLEPIE_LOCATOR_REMOTE_BODY', NamespacedSimplePie::LOCATOR_REMOTE_BODY);
-
-/**
- * All Feed Autodiscovery
- * @see SimplePie::set_autodiscovery_level()
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::LOCATOR_ALL instead.
- */
-define('SIMPLEPIE_LOCATOR_ALL', NamespacedSimplePie::LOCATOR_ALL);
-
-/**
- * No known feed type
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_NONE instead.
- */
-define('SIMPLEPIE_TYPE_NONE', NamespacedSimplePie::TYPE_NONE);
-
-/**
- * RSS 0.90
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_RSS_090 instead.
- */
-define('SIMPLEPIE_TYPE_RSS_090', NamespacedSimplePie::TYPE_RSS_090);
-
-/**
- * RSS 0.91 (Netscape)
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_RSS_091_NETSCAPE instead.
- */
-define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', NamespacedSimplePie::TYPE_RSS_091_NETSCAPE);
-
-/**
- * RSS 0.91 (Userland)
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_RSS_091_USERLAND instead.
- */
-define('SIMPLEPIE_TYPE_RSS_091_USERLAND', NamespacedSimplePie::TYPE_RSS_091_USERLAND);
-
-/**
- * RSS 0.91 (both Netscape and Userland)
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_RSS_091 instead.
- */
-define('SIMPLEPIE_TYPE_RSS_091', NamespacedSimplePie::TYPE_RSS_091);
-
-/**
- * RSS 0.92
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_RSS_092 instead.
- */
-define('SIMPLEPIE_TYPE_RSS_092', NamespacedSimplePie::TYPE_RSS_092);
-
-/**
- * RSS 0.93
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_RSS_093 instead.
- */
-define('SIMPLEPIE_TYPE_RSS_093', NamespacedSimplePie::TYPE_RSS_093);
-
-/**
- * RSS 0.94
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_RSS_094 instead.
- */
-define('SIMPLEPIE_TYPE_RSS_094', NamespacedSimplePie::TYPE_RSS_094);
-
-/**
- * RSS 1.0
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_RSS_10 instead.
- */
-define('SIMPLEPIE_TYPE_RSS_10', NamespacedSimplePie::TYPE_RSS_10);
-
-/**
- * RSS 2.0
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_RSS_20 instead.
- */
-define('SIMPLEPIE_TYPE_RSS_20', NamespacedSimplePie::TYPE_RSS_20);
-
-/**
- * RDF-based RSS
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_RSS_RDF instead.
- */
-define('SIMPLEPIE_TYPE_RSS_RDF', NamespacedSimplePie::TYPE_RSS_RDF);
-
-/**
- * Non-RDF-based RSS (truly intended as syndication format)
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_RSS_SYNDICATION instead.
- */
-define('SIMPLEPIE_TYPE_RSS_SYNDICATION', NamespacedSimplePie::TYPE_RSS_SYNDICATION);
-
-/**
- * All RSS
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_RSS_ALL instead.
- */
-define('SIMPLEPIE_TYPE_RSS_ALL', NamespacedSimplePie::TYPE_RSS_ALL);
-
-/**
- * Atom 0.3
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_ATOM_03 instead.
- */
-define('SIMPLEPIE_TYPE_ATOM_03', NamespacedSimplePie::TYPE_ATOM_03);
-
-/**
- * Atom 1.0
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_ATOM_10 instead.
- */
-define('SIMPLEPIE_TYPE_ATOM_10', NamespacedSimplePie::TYPE_ATOM_10);
-
-/**
- * All Atom
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_ATOM_ALL instead.
- */
-define('SIMPLEPIE_TYPE_ATOM_ALL', NamespacedSimplePie::TYPE_ATOM_ALL);
-
-/**
- * All feed types
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::TYPE_ALL instead.
- */
-define('SIMPLEPIE_TYPE_ALL', NamespacedSimplePie::TYPE_ALL);
-
-/**
- * No construct
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::CONSTRUCT_NONE instead.
- */
-define('SIMPLEPIE_CONSTRUCT_NONE', NamespacedSimplePie::CONSTRUCT_NONE);
-
-/**
- * Text construct
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::CONSTRUCT_TEXT instead.
- */
-define('SIMPLEPIE_CONSTRUCT_TEXT', NamespacedSimplePie::CONSTRUCT_TEXT);
-
-/**
- * HTML construct
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::CONSTRUCT_HTML instead.
- */
-define('SIMPLEPIE_CONSTRUCT_HTML', NamespacedSimplePie::CONSTRUCT_HTML);
-
-/**
- * XHTML construct
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::CONSTRUCT_XHTML instead.
- */
-define('SIMPLEPIE_CONSTRUCT_XHTML', NamespacedSimplePie::CONSTRUCT_XHTML);
-
-/**
- * base64-encoded construct
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::CONSTRUCT_BASE64 instead.
- */
-define('SIMPLEPIE_CONSTRUCT_BASE64', NamespacedSimplePie::CONSTRUCT_BASE64);
-
-/**
- * IRI construct
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::CONSTRUCT_IRI instead.
- */
-define('SIMPLEPIE_CONSTRUCT_IRI', NamespacedSimplePie::CONSTRUCT_IRI);
-
-/**
- * A construct that might be HTML
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::CONSTRUCT_MAYBE_HTML instead.
- */
-define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', NamespacedSimplePie::CONSTRUCT_MAYBE_HTML);
-
-/**
- * All constructs
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::CONSTRUCT_ALL instead.
- */
-define('SIMPLEPIE_CONSTRUCT_ALL', NamespacedSimplePie::CONSTRUCT_ALL);
-
-/**
- * Don't change case
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::SAME_CASE instead.
- */
-define('SIMPLEPIE_SAME_CASE', NamespacedSimplePie::SAME_CASE);
-
-/**
- * Change to lowercase
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::LOWERCASE instead.
- */
-define('SIMPLEPIE_LOWERCASE', NamespacedSimplePie::LOWERCASE);
-
-/**
- * Change to uppercase
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::UPPERCASE instead.
- */
-define('SIMPLEPIE_UPPERCASE', NamespacedSimplePie::UPPERCASE);
-
-/**
- * PCRE for HTML attributes
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::PCRE_HTML_ATTRIBUTE instead.
- */
-define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', NamespacedSimplePie::PCRE_HTML_ATTRIBUTE);
-
-/**
- * PCRE for XML attributes
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::PCRE_XML_ATTRIBUTE instead.
- */
-define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', NamespacedSimplePie::PCRE_XML_ATTRIBUTE);
-
-/**
- * XML Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_XML instead.
- */
-define('SIMPLEPIE_NAMESPACE_XML', NamespacedSimplePie::NAMESPACE_XML);
-
-/**
- * Atom 1.0 Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_ATOM_10 instead.
- */
-define('SIMPLEPIE_NAMESPACE_ATOM_10', NamespacedSimplePie::NAMESPACE_ATOM_10);
-
-/**
- * Atom 0.3 Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_ATOM_03 instead.
- */
-define('SIMPLEPIE_NAMESPACE_ATOM_03', NamespacedSimplePie::NAMESPACE_ATOM_03);
-
-/**
- * RDF Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_RDF instead.
- */
-define('SIMPLEPIE_NAMESPACE_RDF', NamespacedSimplePie::NAMESPACE_RDF);
-
-/**
- * RSS 0.90 Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_RSS_090 instead.
- */
-define('SIMPLEPIE_NAMESPACE_RSS_090', NamespacedSimplePie::NAMESPACE_RSS_090);
-
-/**
- * RSS 1.0 Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_RSS_10 instead.
- */
-define('SIMPLEPIE_NAMESPACE_RSS_10', NamespacedSimplePie::NAMESPACE_RSS_10);
-
-/**
- * RSS 1.0 Content Module Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_RSS_10_MODULES_CONTENT instead.
- */
-define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', NamespacedSimplePie::NAMESPACE_RSS_10_MODULES_CONTENT);
-
-/**
- * RSS 2.0 Namespace
- * (Stupid, I know, but I'm certain it will confuse people less with support.)
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_RSS_20 instead.
- */
-define('SIMPLEPIE_NAMESPACE_RSS_20', NamespacedSimplePie::NAMESPACE_RSS_20);
-
-/**
- * DC 1.0 Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_DC_10 instead.
- */
-define('SIMPLEPIE_NAMESPACE_DC_10', NamespacedSimplePie::NAMESPACE_DC_10);
-
-/**
- * DC 1.1 Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_DC_11 instead.
- */
-define('SIMPLEPIE_NAMESPACE_DC_11', NamespacedSimplePie::NAMESPACE_DC_11);
-
-/**
- * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_W3C_BASIC_GEO instead.
- */
-define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', NamespacedSimplePie::NAMESPACE_W3C_BASIC_GEO);
-
-/**
- * GeoRSS Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_GEORSS instead.
- */
-define('SIMPLEPIE_NAMESPACE_GEORSS', NamespacedSimplePie::NAMESPACE_GEORSS);
-
-/**
- * Media RSS Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_MEDIARSS instead.
- */
-define('SIMPLEPIE_NAMESPACE_MEDIARSS', NamespacedSimplePie::NAMESPACE_MEDIARSS);
-
-/**
- * Wrong Media RSS Namespace. Caused by a long-standing typo in the spec.
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG instead.
- */
-define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', NamespacedSimplePie::NAMESPACE_MEDIARSS_WRONG);
-
-/**
- * Wrong Media RSS Namespace #2. New namespace introduced in Media RSS 1.5.
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG2 instead.
- */
-define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2', NamespacedSimplePie::NAMESPACE_MEDIARSS_WRONG2);
-
-/**
- * Wrong Media RSS Namespace #3. A possible typo of the Media RSS 1.5 namespace.
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG3 instead.
- */
-define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3', NamespacedSimplePie::NAMESPACE_MEDIARSS_WRONG3);
-
-/**
- * Wrong Media RSS Namespace #4. New spec location after the RSS Advisory Board takes it over, but not a valid namespace.
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG4 instead.
- */
-define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4', NamespacedSimplePie::NAMESPACE_MEDIARSS_WRONG4);
-
-/**
- * Wrong Media RSS Namespace #5. A possible typo of the RSS Advisory Board URL.
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_MEDIARSS_WRONG5 instead.
- */
-define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5', NamespacedSimplePie::NAMESPACE_MEDIARSS_WRONG5);
-
-/**
- * iTunes RSS Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_ITUNES instead.
- */
-define('SIMPLEPIE_NAMESPACE_ITUNES', NamespacedSimplePie::NAMESPACE_ITUNES);
-
-/**
- * XHTML Namespace
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::NAMESPACE_XHTML instead.
- */
-define('SIMPLEPIE_NAMESPACE_XHTML', NamespacedSimplePie::NAMESPACE_XHTML);
-
-/**
- * IANA Link Relations Registry
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::IANA_LINK_RELATIONS_REGISTRY instead.
- */
-define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', NamespacedSimplePie::IANA_LINK_RELATIONS_REGISTRY);
-
-/**
- * No file source
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::FILE_SOURCE_NONE instead.
- */
-define('SIMPLEPIE_FILE_SOURCE_NONE', NamespacedSimplePie::FILE_SOURCE_NONE);
-
-/**
- * Remote file source
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::FILE_SOURCE_REMOTE instead.
- */
-define('SIMPLEPIE_FILE_SOURCE_REMOTE', NamespacedSimplePie::FILE_SOURCE_REMOTE);
-
-/**
- * Local file source
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::FILE_SOURCE_LOCAL instead.
- */
-define('SIMPLEPIE_FILE_SOURCE_LOCAL', NamespacedSimplePie::FILE_SOURCE_LOCAL);
-
-/**
- * fsockopen() file source
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::FILE_SOURCE_FSOCKOPEN instead.
- */
-define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', NamespacedSimplePie::FILE_SOURCE_FSOCKOPEN);
-
-/**
- * cURL file source
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::FILE_SOURCE_CURL instead.
- */
-define('SIMPLEPIE_FILE_SOURCE_CURL', NamespacedSimplePie::FILE_SOURCE_CURL);
-
-/**
- * file_get_contents() file source
- * @deprecated since SimplePie 1.7.0, use \SimplePie\SimplePie::FILE_SOURCE_FILE_GET_CONTENTS instead.
- */
-define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', NamespacedSimplePie::FILE_SOURCE_FILE_GET_CONTENTS);
-
-}
-
diff --git a/leed/Update.class.php b/leed/Update.class.php
deleted file mode 100644
index b1af3d9aa6a2ee61e9a155c4d461c605a5b240c0..0000000000000000000000000000000000000000
--- a/leed/Update.class.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-/**
- @nom: Update
- @auteur: Maël ILLOUZ (mael.illouz@cobestran.com)
- @description: Classe de gestion des mises à jour en BDD liées aux améliorations apportées dans Leed
- @todo : Ajouter la possiblité d'executer des fichiers php de maj.
- */
-
-class Update{
-    const FOLDER = '/updates';
-
-    /**
-     * Description : Récupération des fichiers déjà passés lors des anciennes mises à jour.
-     */
-    private static function getUpdateFile(){
-        $updateFile = dirname(__FILE__).Update::FOLDER.'/update.json';
-        if(!file_exists($updateFile)) {
-            if (!touch($updateFile)) {
-                die ('Impossible d\'écrire dans le répertoire .'.dirname($updateFile).'. Merci d\'ajouter les droits necessaires.');
-            }
-        }
-
-        return json_decode(file_get_contents($updateFile),true);
-    }
-
-    private static function addUpdateFile($addFile){
-        $updateFile = dirname(__FILE__).Update::FOLDER.'/update.json';
-        $originFile = Update::getUpdateFile();
-        if(empty($originFile))
-            $originFile = array();
-        $newfile = array_merge($originFile,$addFile);
-        if (is_writable($updateFile)){
-            file_put_contents($updateFile,json_encode($newfile));
-        } else {
-            die ('Impossible d\'écrire dans le fichier .'.$updateFile.'. Merci d\'ajouter les droits nécessaires.');
-        }
-    }
-
-
-    /**
-     * Description : Permet de trouver les fichiers qui n'ont pas encore été joués
-     */
-    private static function getNewPatch() {
-        $files = glob(dirname(__FILE__). Update::FOLDER .'/*.sql');
-        if(empty($files))
-            $files = array();
-
-        $jsonFiles = Update::getUpdateFile();
-
-        $notPassed = array();
-
-        if ($jsonFiles=='') $jsonFiles[0] = array();
-
-        foreach($files as $file){
-            $found = false;
-            foreach($jsonFiles as $jsonfile){
-                if (isset($jsonfile[0])) {
-                    if(in_array(basename($file), $jsonfile)) $found = true;
-                }
-            }
-            if (!$found) $notPassed [] =  basename($file);
-        }
-        return $notPassed;
-    }
-
-    /**
-     * Description : Permet l'execution des fichiers sql non joués
-     * @simulation : true pour ne pas faire les actions en bdd
-     */
-    public static function ExecutePatch($simulation=false) {
-        $newFilesForUpdate = Update::getNewPatch();
-
-        //si aucun nouveau fichier de mise à jour à traiter @return : false
-        if(count($newFilesForUpdate)==0) return false;
-        if (!$simulation) {
-            Functions::purgeRaintplCache();
-            foreach($newFilesForUpdate as $file){
-                // récupération du contenu du sql
-                $sql = file_get_contents(dirname(__FILE__).Update::FOLDER.'/'.$file);
-
-                $conn = MysqlConnector::getInstance()->connection;
-                //on sépare chaque requête par les ;
-                $sql_array = explode (";",$sql);
-                foreach ($sql_array as $val) {
-                    $val = preg_replace('#([-].*)|(\n)#','',$val);
-                    if ($val != '') {
-                        //remplacement des préfixes de table
-                        $val = str_replace('##MYSQL_PREFIX##',MYSQL_PREFIX,$val);
-                        $result = $conn->query($val);
-                        $ficlog = dirname(__FILE__).Update::FOLDER.'/'.substr($file,0,strlen($file)-3).'log';
-                        if (false===$result) {
-                            file_put_contents($ficlog, date('d/m/Y H:i:s').' : SQL : '.$val."\n", FILE_APPEND);
-                            file_put_contents($ficlog, date('d/m/Y H:i:s').' : '.$conn->error."\n", FILE_APPEND);
-                        } else {
-                            file_put_contents($ficlog, date('d/m/Y H:i:s').' : SQL : '.$val."\n", FILE_APPEND);
-                            file_put_contents($ficlog, date('d/m/Y H:i:s').' : '.$conn->affected_rows.' rows affected'."\n", FILE_APPEND);
-                        }
-                    }
-                }
-                unset($conn);
-            }
-            $_SESSION = array();
-            session_unset();
-            session_destroy();
-        }
-        // quand toutes les requêtes ont été executées, on insert le sql dans le json
-        Update::addUpdateFile(array($newFilesForUpdate));
-
-        return true;
-    }
-
-}
-
-?>
diff --git a/leed/User.class.php b/leed/User.class.php
deleted file mode 100644
index c4d9dc19465ab767c1c3bc5218f9ea5a892c6f0f..0000000000000000000000000000000000000000
--- a/leed/User.class.php
+++ /dev/null
@@ -1,233 +0,0 @@
-<?php
-
-/*
- @nom: User
- @auteur: Idleman (http://blog.idleman.fr)
- @description:  Classe de gestion des utilisateurs
- */
-
-class User extends MysqlEntity{
-
-    const OTP_INTERVAL = 30;
-    const OTP_DIGITS   = 8;
-    const OTP_DIGEST   = 'sha1';
-
-    protected $id,$login,$password,$otpSecret;
-    protected $TABLE_NAME = 'user';
-    protected $object_fields =
-    array(
-        'id'=>'key',
-        'login'=>'string',
-        'password'=>'string',
-        'otpSecret'=>'string',
-    );
-
-    protected $object_fields_uniques =
-    array(
-        'login'
-    );
-
-    function __construct(){
-        parent::__construct();
-    }
-
-    function setId($id){
-        $this->id = $id;
-    }
-
-    function isOtpSecretValid($otpSecret) {
-        // Teste si la longueur est d'au moins 8 caractères
-        // et en Base32: [A-Z] + [2-7]
-        return is_string($otpSecret) && preg_match('/^[a-zA-Z2-7]{8,}$/', $otpSecret);
-    }
-
-    protected function getOtpControler() {
-        return new \OTPHP\TOTP($this->otpSecret, array('interval'=>self::OTP_INTERVAL, 'digits'=>self::OTP_DIGITS, 'digest'=>self::OTP_DIGEST));
-    }
-
-    function getOtpKey() {
-        $otp = $this->getOtpControler();
-        return str_pad($otp->now(), $otp->digits, '0', STR_PAD_LEFT);
-    }
-
-    function exist($login,$password,$salt='',$otpEntered=Null){
-        $userManager = new User();
-        $user = $userManager->load(array('login'=>$login,'password'=>User::encrypt($password,$salt)));
-
-        if (false!=$user) {
-            $otpSecret = $user->otpSecret;
-
-            global $configurationManager;
-            switch (True) {
-                case !$configurationManager->get('otpEnabled'):
-                case empty($otpSecret) && empty($otpEntered):
-                    // Pas d'OTP s'il est désactivé dans la configuration où s'il n'est pas demandé et fourni.
-                    return $user;
-            }
-            $otp = $user->getOtpControler();
-            if ($otp->verify($otpEntered) || $otp->verify($otpEntered, time()-10)) {
-                return $user;
-            }
-        }
-
-        return false;
-    }
-
-    static function get($login){
-        $userManager = new User();
-        return $userManager->load(array('login'=>$login,));
-    }
-
-    function getToken() {
-        $hasPassword = !empty($this->password);
-        $hasLogin = !empty($this->login);
-        assert($hasLogin);
-        assert($hasPassword);
-        return sha1($this->password.$this->login);
-    }
-
-    public function add($login = false, $password = false, $salt = false, $logger = false) {
-        if(!$logger) {
-            require_once('Logger.class.php');
-            $logger = new Logger('settings');
-        }
-        if(empty($login)) {
-            $logger->appendLogs(_t("USER_ADD_MISSING_LOGIN"));
-        }
-        $existingUser = $this->load(array('login' => $login));
-        if($existingUser instanceof User) {
-            $logger->appendLogs(_t("USER_ADD_DUPLICATE"));
-            $logger->save();
-            return false;
-        }
-        if(empty($password)) {
-            $logger->appendLogs(_t("USER_ADD_MISSING_PASSWORD"));
-        }
-        if($logger->hasLogs()) {
-            $logger->save();
-            return false;
-        }
-        $this->setLogin($login);
-        $this->setPassword($password, $salt);
-        $this->save();
-        $this->createSideTables($login);
-        $logger->appendLogs(_t("USER_ADD_OK"). ' '.$login);
-        $logger->save();
-        return true;
-    }
-
-    public function remove($userId) {
-        require_once('Logger.class.php');
-        $logger = new Logger('settings');
-        if(empty($userId)) {
-            $logger->appendLogs(_t("USER_DEL_MISSING_ID"));
-            $logger->save();
-            return false;
-        }
-        $user = $this->load(array('id' => $userId));
-        if(!$user) {
-            $logger->appendLogs(_t("USER_DEL_UNKNOWN_ID").' '.$userId);
-            $logger->save();
-            return false;
-        }
-        $this->setLogin($user->getLogin());
-        $this->deleteSideTables();
-        $this->delete(array('id' => $userId));
-        $logger->appendLogs(_t("USER_DEL_OK").$user->getLogin());
-        $logger->save();
-        return true;
-    }
-
-    protected function createSideTables() {
-        $this->manageSideTables();
-    }
-
-    protected function deleteSideTables() {
-        $this->manageSideTables('remove');
-    }
-
-    protected function manageSideTables($action = 'add') {
-        $actionMethod = $action === 'add' ? 'create' : 'destroy';
-        $feedManager = new Feed();
-        $feedManager->$actionMethod();
-        $eventManager = new Event();
-        $eventManager->$actionMethod();
-        $folderManager = new Folder();
-        $folderManager->$actionMethod();
-        if($action === 'add' && $folderManager->rowCount() === '0') {
-            $folderManager->setName(_t('GENERAL_FOLDER'));
-            $folderManager->setParent(-1);
-            $folderManager->setIsopen(1);
-            $folderManager->save();
-        }
-    }
-
-    static function existAuthToken($auth=null){
-        $result = false;
-        $userManager = new User();
-        $users = $userManager->populate('id');
-        $phpAuth = isset($_SERVER['PHP_AUTH_USER']) ? strtolower($_SERVER['PHP_AUTH_USER']) : false;
-        if (empty($auth)) $auth = @$_COOKIE['leedStaySignedIn'];
-        foreach($users as $user){
-            if ($user->getToken()==$auth || strtolower($user->login)===$phpAuth){
-                $result = $user;
-                break;
-            }
-        }
-        return $result;
-    }
-
-    static function generateSalt() {
-        return ''.mt_rand().mt_rand();
-    }
-
-    function setStayConnected() {
-        ///@TODO: set the current web directory, here and on del
-        setcookie('leedStaySignedIn', $this->getToken(), time()+31536000);
-    }
-
-    static function delStayConnected() {
-        setcookie('leedStaySignedIn', '', -1);
-    }
-
-    function getId(){
-        return $this->id;
-    }
-
-    function getLogin(){
-        return $this->login;
-    }
-
-    function setLogin($login){
-        $this->login = $login;
-    }
-
-    function getPassword(){
-        return $this->password;
-    }
-
-    function setPassword($password,$salt=''){
-        $this->password = User::encrypt($password,$salt);
-    }
-
-    function getOtpSecret(){
-        return $this->otpSecret;
-    }
-
-    function setOtpSecret($otpSecret){
-        $this->otpSecret = $otpSecret;
-    }
-
-    function resetPassword($resetPassword, $salt=''){
-        $this->setPassword($resetPassword, $salt);
-        $this->otpSecret = '';
-        $this->save();
-    }
-
-    static function encrypt($password, $salt=''){
-        return sha1($password.$salt);
-    }
-
-}
-
-?>
diff --git a/leed/about.php b/leed/about.php
deleted file mode 100644
index 4f10c00aa7f3b07f7914842eb7755c3221765672..0000000000000000000000000000000000000000
--- a/leed/about.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-/*
- @nom: about
- @auteur: Idleman (http://blog.idleman.fr)
- @description: Page "A propos" d'information contextuelles sur le projet
- */
-
-require_once('header.php');
-
-$tpl->assign('otpEnabled', $configurationManager->get('otpEnabled'));
-$view = 'about';
-require_once('footer.php');
-
-?>
diff --git a/leed/action.php b/leed/action.php
deleted file mode 100644
index 470cb1d4ea35eac37f48da93ca4bec2b911bc192..0000000000000000000000000000000000000000
--- a/leed/action.php
+++ /dev/null
@@ -1,599 +0,0 @@
-<?php
-
-/*
- @nom: action
- @auteur: Idleman (http://blog.idleman.fr)
- @description: Page de gestion des évenements non liés a une vue particulière (appels ajax, requetes sans resultats etc...)
- */
-
-if(!ini_get('safe_mode')) @set_time_limit(0);
-require_once("common.php");
-
-///@TODO: déplacer dans common.php?
-$commandLine = 'cli'==php_sapi_name();
-
-if ($commandLine) {
-    $action = 'commandLine';
-} else {
-    $action = @$_['action'];
-}
-///@TODO: pourquoi ne pas refuser l'accès dès le début ?
-Plugin::callHook("action_pre_case", array(&$_,$myUser));
-
-//Execution du code en fonction de l'action
-switch ($action){
-    case 'commandLine':
-    case 'synchronize':
-        require_once("SimplePie.class.php");
-        $syncCode = $configurationManager->get('synchronisationCode');
-        $syncGradCount = $configurationManager->get('syncGradCount');
-        if (   false==$myUser
-            && !$commandLine
-            && !(isset($_['code'])
-                && $configurationManager->get('synchronisationCode')!=null
-                && $_['code']==$configurationManager->get('synchronisationCode')
-            )
-        ) {
-            die(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        }
-        Functions::triggerDirectOutput();
-
-        if (!$commandLine){
-            echo '<html>
-                <head>
-                <link rel="stylesheet" href="./templates/'.$theme.'/css/style.css">
-                <meta name="referrer" content="no-referrer" />
-                </head>
-                <body>
-                <div class="sync">';
-        }
-        $synchronisationType = $configurationManager->get('synchronisationType');
-
-        $synchronisationCustom = array();
-        Plugin::callHook("action_before_synchronisationtype", array(&$synchronisationCustom,&$synchronisationType,&$commandLine,$configurationManager,$start));
-        if(isset($synchronisationCustom['type'])){
-            $feeds = $synchronisationCustom['feeds'];
-            $syncTypeStr = _t('SYNCHRONISATION_TYPE').' : '._t($synchronisationCustom['type']);
-        }elseif('graduate'==$synchronisationType){
-            // sélectionne les 10 plus vieux flux
-            $feeds = $feedManager->loadAll(null,'lastupdate', $syncGradCount);
-            $syncTypeStr = _t('SYNCHRONISATION_TYPE').' : '._t('GRADUATE_SYNCHRONISATION');
-        }else{
-            // sélectionne tous les flux, triés par le nom
-            $feeds = $feedManager->populate('name');
-            $syncTypeStr = _t('SYNCHRONISATION_TYPE').' : '._t('FULL_SYNCHRONISATION');
-        }
-
-        if(!isset($synchronisationCustom['no_normal_synchronize'])){
-            $feedManager->synchronize($feeds, $syncTypeStr, $commandLine, $configurationManager, $start);
-        }
-    break;
-
-
-    case 'readAll':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        $whereClause = array();
-        $whereClause['unread'] = '1';
-        if(isset($_['feed']))$whereClause['feed'] = $_['feed'];
-        if(isset($_['last-event-id']))$whereClause['id'] = '<= ' . $_['last-event-id'];
-        $eventManager->change(array('unread'=>'0'),$whereClause);
-        if(!Functions::isAjaxCall()){
-            header('location: ./');
-        }
-    break;
-
-    case 'readFolder':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-
-        $feeds = $feedManager->loadAllOnlyColumn('id',array('folder'=>$_['folder']));
-
-        foreach($feeds as $feed){
-            $whereClause['feed'] = $feed->getId();
-            if(isset($_['last-event-id']))$whereClause['id'] = '<= ' . $_['last-event-id'];
-            $eventManager->change(array('unread'=>'0'),$whereClause);
-        }
-
-        if (!Functions::isAjaxCall()){
-            header('location: ./');
-        }
-
-    break;
-
-    case 'updateConfiguration':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-
-            //Ajout des préférences et réglages
-            $configurationManager->put('root',(substr($_['root'], strlen($_['root'])-1)=='/'?$_['root']:$_['root'].'/'));
-            $configurationManager->put('articleDisplayAnonymous',$_['articleDisplayAnonymous']);
-            $configurationManager->put('articlePerPages',$_['articlePerPages']);
-            $configurationManager->put('articleDisplayLink',$_['articleDisplayLink']);
-            $configurationManager->put('articleDisplayDate',$_['articleDisplayDate']);
-            $configurationManager->put('articleDisplayAuthor',$_['articleDisplayAuthor']);
-            $configurationManager->put('articleDisplayHomeSort',$_['articleDisplayHomeSort']);
-            $configurationManager->put('articleDisplayFolderSort',$_['articleDisplayFolderSort']);
-            $configurationManager->put('articleDisplayMode',$_['articleDisplayMode']);
-            $configurationManager->put('synchronisationType',$_['synchronisationType']);
-            $configurationManager->put('synchronisationEnableCache',$_['synchronisationEnableCache']);
-            $configurationManager->put('synchronisationForceFeed',$_['synchronisationForceFeed']);
-            $configurationManager->put('feedMaxEvents',$_['feedMaxEvents']);
-            $configurationManager->put('language',$_['ChgLanguage']);
-            $configurationManager->put('theme',$_['ChgTheme']);
-            $configurationManager->put('otpEnabled',$_['otpEnabled']);
-
-            if(trim($_['password'])!='') {
-                $salt = User::generateSalt();
-                $userManager->change(array('password'=>User::encrypt($_['password'], $salt)),array('id'=>$myUser->getId()));
-                /* /!\ En multi-utilisateur, il faudra changer l'information au
-                niveau du compte lui-même et non au niveau du déploiement comme
-                ici. C'est ainsi parce que c'est plus efficace de stocker le sel
-                dans la config que dans le fichier de constantes, difficile à
-                modifier. */
-                $oldSalt = $configurationManager->get('cryptographicSalt');
-                if (empty($oldSalt))
-                    /* Pendant la migration à ce système, les déploiements
-                    ne posséderont pas cette donnée. */
-                    $configurationManager->add('cryptographicSalt', $salt);
-                else
-                    $configurationManager->change(array('value'=>$salt), array('key'=>'cryptographicSalt'));
-
-            }
-
-            # Modifications dans la base de données, la portée courante et la sesssion
-            # @TODO: gérer cela de façon centralisée
-            $otpSecret = $_['otpSecret'];
-            if ($myUser->isOtpSecretValid($otpSecret)) {
-                $userManager->change(array('login'=>$_['login'], 'otpSecret'=>$otpSecret),array('id'=>$myUser->getId()));
-                $myUser->setLogin($_['login']);
-                $myUser->setOtpSecret($otpSecret);
-                $_SESSION['currentUser'] = serialize($myUser);
-            }
-
-    header('location: ./settings.php#preferenceBloc');
-    break;
-
-
-    case 'purgeEvents':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        $eventManager->truncate();
-        header('location: ./settings.php');
-    break;
-
-
-    case 'purgeCache':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        Functions::purgeRaintplCache();
-        header('location: ./settings.php');
-    break;
-
-
-    case 'exportFeed':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-            /*********************/
-        /** Export **/
-        /*********************/
-        if(isset($_POST['exportButton'])){
-            $opml = new Opml();
-            $xmlStream = $opml->export();
-
-            header('Content-Description: File Transfer');
-            header('Content-Type: application/octet-stream');
-            header('Content-Disposition: attachment; filename=leed-'.date('d-m-Y').'.opml');
-            header('Content-Transfer-Encoding: binary');
-            header('Expires: 0');
-            header('Cache-Control: must-revalidate');
-            header('Pragma: public');
-            header('Content-Length: ' . strlen($xmlStream));
-            /*
-            //A decommenter dans le cas ou on a des pb avec ie
-            if(preg_match('/msie|(microsoft internet explorer)/i', $_SERVER['HTTP_USER_AGENT'])){
-              header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
-              header('Pragma: public');
-            }else{
-              header('Pragma: no-cache');
-            }
-            */
-            ob_clean();
-            flush();
-            echo $xmlStream;
-        }
-    break;
-
-
-    case 'importForm':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        echo '<html style="height:auto;"><link rel="stylesheet" href="templates/'.$theme.'/css/style.css">
-                <body style="height:auto;">
-                    <form action="action.php?action=importFeed" method="POST" enctype="multipart/form-data">
-                    <p>'._t('OPML_FILE').' : <input name="newImport" type="file"/> <button name="importButton">'._t('IMPORT').'</button></p>
-                    <p>'._t('IMPORT_COFFEE_TIME').'</p>
-                    </form>
-                </body>
-            </html>
-
-            ';
-    break;
-
-    case 'synchronizeForm':
-     if(isset($myUser) && $myUser!=false){
-        echo '<link rel="stylesheet" href="templates/'.$theme.'/css/style.css">
-                <a class="button" href="action.php?action=synchronize">'._t('SYNCHRONIZE_NOW').'</a>
-                    <p>'._t('SYNCHRONIZE_COFFEE_TIME').'</p>
-
-            ';
-        }else{
-            echo _t('YOU_MUST_BE_CONNECTED_ACTION');
-        }
-
-    break;
-
-    case 'changeFolderState':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        $folderManager->change(array('isopen'=>$_['isopen']),array('id'=>$_['id']));
-    break;
-
-    case 'importFeed':
-        // On ne devrait pas mettre de style ici.
-        echo "<html>
-            <style>
-                a {
-                    color:#F16529;
-                }
-
-                html,body{
-                        font-family:Verdana;
-                        font-size: 11px;
-                }
-                .error{
-                        background-color:#C94141;
-                        color:#ffffff;
-                        padding:5px;
-                        border-radius:5px;
-                        margin:10px 0px 10px 0px;
-                        box-shadow: 0 0 3px 0 #810000;
-                    }
-                .error a{
-                        color:#ffffff;
-                }
-                </style>
-            </style><body>
-\n";
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        if(!isset($_POST['importButton'])) break;
-        $opml = new Opml();
-        echo "<h3>"._t('IMPORT')."</h3><p>"._t('PENDING')."</p>\n";
-        try {
-            $errorOutput = $opml->import($_FILES['newImport']['tmp_name']);
-        } catch (Exception $e) {
-            $errorOutput = array($e->getMessage());
-        }
-        if (empty($errorOutput)) {
-            echo "<p>"._t('IMPORT_NO_PROBLEM')."</p>\n";
-        } else {
-            echo "<div class='error'>"._t('IMPORT_ERROR')."\n";
-            foreach($errorOutput as $line) {
-                echo "<p>$line</p>\n";
-            }
-            echo "</div>";
-        }
-        if (!empty($opml->alreadyKnowns)) {
-            echo "<h3>"._t('IMPORT_FEED_ALREADY_KNOWN')." : </h3>\n<ul>\n";
-            foreach($opml->alreadyKnowns as $alreadyKnown) {
-                foreach($alreadyKnown as &$elt) $elt = htmlspecialchars($elt);
-                $text = Functions::truncate($alreadyKnown->feedName, 60);
-                echo "<li><a target='_parent' href='{$alreadyKnown->xmlUrl}'>"
-                    ."{$text}</a></li>\n";
-            }
-            echo "</ul>\n";
-        }
-        $syncLink = "action.php?action=synchronize&format=html";
-        echo "<p>";
-        echo "<a href='$syncLink' style='text-decoration:none;font-size:3em'>"
-            ."↺</a>";
-        echo "<a href='$syncLink'>"._t('CLIC_HERE_SYNC_IMPORT')."</a>";
-        echo "<p></body></html>\n";
-    break;
-
-
-    case 'addFeed':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        require_once("SimplePie.class.php");
-        if(!isset($_['newUrl'])) break;
-        $newFeed = new Feed();
-        $newFeed->setUrl(Functions::clean_url($_['newUrl']));
-        if ($newFeed->notRegistered()) {
-            $newFeed->setFolder(
-                (isset($_['newUrlCategory'])?$_['newUrlCategory']:1)
-            );
-            $newFeed->save();
-            $enableCache = ($configurationManager->get('synchronisationEnableCache')=='')?0:$configurationManager->get('synchronisationEnableCache');
-            $forceFeed = ($configurationManager->get('synchronisationForceFeed')=='')?0:$configurationManager->get('synchronisationForceFeed');
-            $newFeed->parse(time(), $_, $enableCache, $forceFeed);
-            Plugin::callHook("action_after_addFeed", array(&$newFeed));
-        } else {
-            $logger = new Logger('settings');
-            $logger->appendLogs(_t("FEED_ALREADY_STORED"));
-            $logger->save();
-        }
-        header('location: ./settings.php#manageBloc');
-    break;
-
-    case 'changeFeedFolder':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        if(isset($_['feed'])){
-            $feedManager->change(array('folder'=>$_['folder']),array('id'=>$_['feed']));
-        }
-        header('location: ./settings.php');
-    break;
-
-    case 'removeFeed':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        if(isset($_GET['id'])){
-            $feedManager->delete(array('id'=>$_['id']));
-            $eventManager->delete(array('feed'=>$_['id']));
-            Plugin::callHook("action_after_removeFeed", array($_['id']));
-        }
-        header('location: ./settings.php');
-    break;
-
-    case 'addFolder':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        if(isset($_['newFolder'])){
-            $folder = new Folder();
-            if($folder->rowCount(array('name'=>$_['newFolder']))==0){
-                $folder->setParent(-1);
-                $folder->setIsopen(0);
-                $folder->setName($_['newFolder']);
-                $folder->save();
-            }
-        }
-        header('location: ./settings.php');
-    break;
-
-
-    case 'renameFolder':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        if(isset($_['id'])){
-            $folderManager->change(array('name'=>$_['name']),array('id'=>$_['id']));
-        }
-    break;
-
-    case 'renameFeed':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        if(isset($_['id'])){
-            $feedManager->change(array('name'=>$_['name'],'url'=>Functions::clean_url($_['url'])),array('id'=>$_['id']));
-        }
-    break;
-
-    case 'removeFolder':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-        if(isset($_['id']) && is_numeric($_['id']) && $_['id']>0){
-            $eventManager->customQuery('DELETE FROM `'.MYSQL_PREFIX.'event` WHERE `'.MYSQL_PREFIX.'event`.`feed` in (SELECT `'.MYSQL_PREFIX.'feed`.`id` FROM `'.MYSQL_PREFIX.'feed` WHERE `'.MYSQL_PREFIX.'feed`.`folder` =\''.intval($_['id']).'\') ;');
-            $feedManager->delete(array('folder'=>$_['id']));
-            $folderManager->delete(array('id'=>$_['id']));
-        }
-        header('location: ./settings.php');
-    break;
-
-    case 'readContent':
-        if($myUser==false) {
-            $response_array['status'] = 'noconnect';
-            $response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
-            header('Content-type: application/json');
-            echo json_encode($response_array);
-            exit();
-        }
-        if(isset($_['id'])){
-            $event = $eventManager->load(array('id'=>$_['id']));
-            $eventManager->change(array('unread'=>'0'),array('id'=>$_['id']));
-        }
-    break;
-
-    case 'unreadContent':
-        if($myUser==false) {
-            $response_array['status'] = 'noconnect';
-            $response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
-            header('Content-type: application/json');
-            echo json_encode($response_array);
-            exit();
-        }
-        if(isset($_['id'])){
-            $event = $eventManager->load(array('id'=>$_['id']));
-            $eventManager->change(array('unread'=>'1'),array('id'=>$_['id']));
-        }
-    break;
-
-    case 'addFavorite':
-        if($myUser==false) {
-            $response_array['status'] = 'noconnect';
-            $response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
-            header('Content-type: application/json');
-            echo json_encode($response_array);
-            exit();
-        }
-        $eventManager->change(array('favorite'=>'1'),array('id'=>$_['id']));
-    break;
-
-    case 'removeFavorite':
-        if($myUser==false) {
-            $response_array['status'] = 'noconnect';
-            $response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
-            header('Content-type: application/json');
-            echo json_encode($response_array);
-            exit();
-        }
-        $eventManager->change(array('favorite'=>'0'),array('id'=>$_['id']));
-    break;
-
-    case 'login':
-
-        define('RESET_PASSWORD_FILE', 'resetPassword');
-        if (file_exists(RESET_PASSWORD_FILE)) {
-            /* Pour réinitialiser le mot de passe :
-             * créer le fichier RESET_PASSWORD_FILE vide.
-             * Le nouveau mot de passe sera celui fourni à la connexion.
-             */
-            @unlink(RESET_PASSWORD_FILE);
-            if (file_exists(RESET_PASSWORD_FILE)) {
-                $message = 'Unable to remove "'.RESET_PASSWORD_FILE.'"!';
-                /* Pas supprimable ==> on ne remet pas à zéro */
-            } else {
-                $resetPassword = $_['password'];
-                $hasResetPassword = !empty($resetPassword);
-                assert($hasResetPassword);
-                $tmpUser = User::get($_['login']);
-                if (false===$tmpUser) {
-                    $message = "Unknown user '{$_['login']}'! No password reset.";
-                } else {
-                    $tmpUser->resetPassword($resetPassword, $configurationManager->get('cryptographicSalt'));
-                    $message = "User '{$_['login']}' (id={$tmpUser->getId()}) Password reset to '$resetPassword'.";
-                }
-            }
-            error_log($message);
-        }
-
-        if(isset($_['usr'])){
-            $user = User::existAuthToken($_['usr']);
-            if($user==false){
-                exit("error"); //@TODO: traduire
-            }else{
-                $_SESSION['currentUser'] = serialize($user);
-                header('location: ./action.php?action=addFeed&newUrl='.$_['newUrl']);
-                exit();
-            }
-        }else{
-            $isOtpEnabled = (bool) $configurationManager->get('otpEnabled');
-            if((!isset($_['login']) || empty($_['login']) || !is_string($_['login']))
-                || (!isset($_['password']) || empty($_['password']) || !is_string($_['password']))
-                || ($isOtpEnabled
-                    && (!isset($_['otp']) || empty($_['otp']) || !is_string($_['otp']))
-                )
-            ) {
-                error_log("Leed: wrong login action detected");
-                header('location: ./?action=wrongLogin');
-                exit;
-            }
-            $salt = $configurationManager->get('cryptographicSalt');
-            if (empty($salt)) $salt = '';
-            if($isOtpEnabled) {
-                $user = $userManager->exist($_['login'],$_['password'],$salt,$_['otp']);
-            } else {
-                $user = $userManager->exist($_['login'],$_['password'],$salt);
-            }
-            if($user==false){
-                error_log("Leed: wrong login for '".$_['login']."'");
-                header('location: ./?action=wrongLogin');
-            }else{
-                $_SESSION['currentUser'] = serialize($user);
-                if (isset($_['rememberMe'])) $user->setStayConnected();
-                header('location: ./');
-            }
-            exit();
-        }
-
-
-
-    break;
-
-    case 'changePluginState':
-        if($myUser==false) exit(_t('YOU_MUST_BE_CONNECTED_ACTION'));
-
-        if($_['state']=='0'){
-            Plugin::enabled($_['plugin']);
-
-        }else{
-            Plugin::disabled($_['plugin']);
-        }
-        header('location: ./settings.php#pluginBloc');
-    break;
-
-
-
-    case 'logout':
-        User::delStayConnected();
-        $_SESSION = array();
-        session_unset();
-        session_destroy();
-        header('location: ./');
-    break;
-
-    case 'displayOnlyUnreadFeedFolder':
-        if($myUser==false) {
-            $response_array['status'] = 'noconnect';
-            $response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
-            header('Content-type: application/json');
-            echo json_encode($response_array);
-            exit();
-        }
-        $configurationManager->put('displayOnlyUnreadFeedFolder',$_['displayOnlyUnreadFeedFolder']);
-    break;
-
-    case 'displayFeedIsVerbose':
-        if($myUser==false) {
-            $response_array['status'] = 'noconnect';
-            $response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
-            header('Content-type: application/json');
-            echo json_encode($response_array);
-            exit();
-        }
-        // changement du statut isverbose du feed
-        $feed = new Feed();
-        $feed = $feed->getById($_['idFeed']);
-        $feed->setIsverbose(($_['displayFeedIsVerbose']=="0"?1:0));
-        $feed->save();
-        break;
-
-    case 'optionFeedIsVerbose':
-        if($myUser==false) {
-            $response_array['status'] = 'noconnect';
-            $response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
-            header('Content-type: application/json');
-            echo json_encode($response_array);
-            exit();
-        }
-        // changement du statut de l'option
-        $configurationManager = new Configuration();
-        $conf = $configurationManager->getAll();
-        $configurationManager->put('optionFeedIsVerbose',($_['optionFeedIsVerbose']=="0"?0:1));
-
-        break;
-
-    case 'articleDisplayMode':
-        if($myUser==false) {
-            $response_array['status'] = 'noconnect';
-            $response_array['texte'] = _t('YOU_MUST_BE_CONNECTED_ACTION');
-            header('Content-type: application/json');
-            echo json_encode($response_array);
-            exit();
-        }
-        // chargement du content de l'article souhaité
-        $newEvent = new Event();
-        $event = $newEvent->getById($_['event_id']);
-
-        if ($_['articleDisplayMode']=='content'){
-            //error_log(print_r($_SESSION['events'],true));
-            $content = $event->getContent();
-        } else {
-            $content = $event->getDescription();
-        }
-        echo $content;
-
-        break;
-
-    default:
-        require_once("SimplePie.class.php");
-        Plugin::callHook("action_post_case", array(&$_,$myUser));
-        //exit('0');
-    break;
-
-    //Installation d'un nouveau plugin
-    case 'installPlugin':
-        Plugin::install($_['zip']);
-    break;
-    case 'getGithubMarket':
-        $plugin = new Plugin();
-        $plugin->getGithubMarketRepos();
-    break;
-}
-
-
-?>
diff --git a/leed/article.php b/leed/article.php
deleted file mode 100644
index b992068dace7398e4315cc07e08b0103f7d2dfcf..0000000000000000000000000000000000000000
--- a/leed/article.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-
-/*
- @nom: article
- @auteur: Maël ILLOUZ (mael.illouz@cobestran.com)
- @description: Page de gestion de l'affichage des articles. Sera utilisé de base ainsi que pour le scroll infini
- */
-
-include ('common.php');
-
-Plugin::callHook("index_pre_treatment", array(&$_));
-
-$view = "article";
-$articleConf = array();
-//recuperation de tous les flux
-$allFeeds = $feedManager->getFeedsPerFolder();
-$tpl->assign('allFeeds',$allFeeds);
-$scroll = isset($_['scroll']) ? $_['scroll'] : 0;
-$tpl->assign('scrollpage',$scroll);
-// récupération des variables pour l'affichage
-$articleConf['articlePerPages'] = (int) $configurationManager->get('articlePerPages');
-$articleDisplayLink = $configurationManager->get('articleDisplayLink');
-$articleDisplayDate = $configurationManager->get('articleDisplayDate');
-$articleDisplayAuthor = $configurationManager->get('articleDisplayAuthor');
-$articleDisplayHomeSort = $configurationManager->get('articleDisplayHomeSort');
-$articleDisplayFolderSort = $configurationManager->get('articleDisplayFolderSort');
-$articleDisplayMode = $configurationManager->get('articleDisplayMode');
-$optionFeedIsVerbose = $configurationManager->get('optionFeedIsVerbose');
-
-$tpl->assign('articleDisplayAuthor',$articleDisplayAuthor);
-$tpl->assign('articleDisplayDate',$articleDisplayDate);
-$tpl->assign('articleDisplayLink',$articleDisplayLink);
-$tpl->assign('articleDisplayMode',$articleDisplayMode);
-
-if(isset($_['hightlighted'])) {
-    $hightlighted = $_['hightlighted'];
-    $tpl->assign('hightlighted',$hightlighted);
-}
-
-$tpl->assign('time',$_SERVER['REQUEST_TIME']);
-
-$target = '`'.MYSQL_PREFIX.'event`.`title`,`'.MYSQL_PREFIX.'event`.`unread`,`'.MYSQL_PREFIX.'event`.`favorite`,`'.MYSQL_PREFIX.'event`.`feed`,';
-if($articleDisplayMode=='summary') $target .= '`'.MYSQL_PREFIX.'event`.`description`,';
-if($articleDisplayMode=='content') $target .= '`'.MYSQL_PREFIX.'event`.`content`,';
-if($articleDisplayLink) $target .= '`'.MYSQL_PREFIX.'event`.`link`,';
-if($articleDisplayDate) $target .= '`'.MYSQL_PREFIX.'event`.`pubdate`,';
-if($articleDisplayAuthor) $target .= '`'.MYSQL_PREFIX.'event`.`creator`,';
-$target .= '`'.MYSQL_PREFIX.'event`.`id`';
-
-$nblus = isset($_['nblus']) ? $_['nblus'] : 0;
-$articleConf['startArticle'] = ($scroll*$articleConf['articlePerPages'])-$nblus;
-if ($articleConf['startArticle'] < 0) $articleConf['startArticle']=0;
-$action = $_['action'];
-$tpl->assign('action',$action);
-
-$filter = array();
-Plugin::callHook("article_pre_action", array(&$_,&$filter,&$articleConf));
-switch($action){
-    /* AFFICHAGE DES EVENEMENTS D'UN FLUX EN PARTICULIER */
-    case 'selectedFeed':
-        $currentFeed = $feedManager->getById($_['feed']);
-        $allowedOrder = array('date'=>'pubdate DESC','older'=>'pubdate','unread'=>'unread DESC,pubdate DESC');
-        $order = (isset($_['order'])?$allowedOrder[$_['order']]:$allowedOrder['unread']);
-        $events = $currentFeed->getEvents($order,$articleConf['startArticle'],$articleConf['articlePerPages'],$target,$filter);
-    break;
-    /* AFFICHAGE DES EVENEMENTS D'UN DOSSIER EN PARTICULIER */
-    case 'selectedFolder':
-        $currentFolder = $folderManager->getById($_['folder']);
-        if($articleDisplayFolderSort) {$order = '`'.MYSQL_PREFIX.'event`.`pubdate` desc';} else {$order = '`'.MYSQL_PREFIX.'event`.`pubdate` asc';}
-        $events = $currentFolder->getEvents($order,$articleConf['startArticle'],$articleConf['articlePerPages'],$target,$filter);
-    break;
-    /* AFFICHAGE DES EVENEMENTS FAVORIS */
-    case 'favorites':
-        $filter['favorite'] = 1;
-        $events = $eventManager->loadAllOnlyColumn($target,$filter,'pubdate DESC',$articleConf['startArticle'].','.$articleConf['articlePerPages']);
-    break;
-    /* AFFICHAGE DES EVENEMENTS NON LUS (COMPORTEMENT PAR DEFAUT) */
-    case 'unreadEvents':
-    default:
-        $filter['unread'] = 1;
-        if($articleDisplayHomeSort) {$order = 'pubdate desc';} else {$order = 'pubdate asc';}
-        if($optionFeedIsVerbose) {
-            $events = $eventManager->loadAllOnlyColumn($target,$filter,$order,$articleConf['startArticle'].','.$articleConf['articlePerPages']);
-        } else {
-            $events = $eventManager->getEventsNotVerboseFeed($order,$articleConf['startArticle'],$articleConf['articlePerPages'],$target);
-        }
-        break;
-}
-$tpl->assign('events',$events);
-$tpl->assign('scroll',$scroll);
-$view = "article";
-Plugin::callHook("index_post_treatment", array(&$events));
-$html = $tpl->draw($view);
-
-?>
diff --git a/leed/common.php b/leed/common.php
deleted file mode 100755
index d5dba232d91b77dc8c25cba49c28aefe531f22a9..0000000000000000000000000000000000000000
--- a/leed/common.php
+++ /dev/null
@@ -1,123 +0,0 @@
-<?php
-
-/*
- @nom: common
- @auteur: Idleman (http://blog.idleman.fr)
- @description: Page incluse dans tous (ou presque) les fichiers du projet, inclus les entitées SQL et récupère/traite les variables de requetes
- */
-
-define('LEED_VERSION_NUMBER','1.12.0');
-define('LEED_VERSION_NAME','dev');
-
-/* Assure la compatibilité des greffons utilisant ces anciennes constantes.
- * Cela doit rester en place jusque Leed v2.0.
- */
-if (!defined('VERSION_NUMBER')) define('VERSION_NUMBER', LEED_VERSION_NUMBER);
-if (!defined('VERSION_NAME')) define('VERSION_NAME', LEED_VERSION_NAME);
-
-/* ---------------------------------------------------------------- */
-// Mise en place d'un timezone par default pour utiliser les fonction de date en php
-$timezone_default = 'Europe/Paris'; // valeur par défaut :)
-date_default_timezone_set($timezone_default);
-$timezone_phpini = ini_get('date.timezone');
-if (($timezone_phpini!='') && (strcmp($timezone_default, $timezone_phpini))) {
-    date_default_timezone_set($timezone_phpini);
-}
-/* ---------------------------------------------------------------- */
-$cookiedir = '';
-if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/';
-session_set_cookie_params(0, $cookiedir);
-session_start();
-mb_internal_encoding('UTF-8'); // UTF8 pour fonctions mb_*
-$start=microtime(true);
-require_once('constant.php');
-require_once('RainTPL.php');
-require_once('i18n.php');
-require_once('otphp/lib/otphp.php');
-class_exists('Functions') or require_once('Functions.class.php');
-class_exists('Plugin') or require_once('Plugin.class.php');
-class_exists('MysqlEntity') or require_once('MysqlEntity.class.php');
-class_exists('Update') or require_once('Update.class.php');
-class_exists('Feed') or require_once('Feed.class.php');
-class_exists('Event') or require_once('Event.class.php');
-class_exists('User') or require_once('User.class.php');
-class_exists('Folder') or require_once('Folder.class.php');
-class_exists('Configuration') or require_once('Configuration.class.php');
-class_exists('Opml') or require_once('Opml.class.php');
-class_exists('Logger') or require_once('Logger.class.php');
-
-
-//error_reporting(E_ALL);
-
-//Calage de la date
-date_default_timezone_set('Europe/Paris');
-
-$configurationManager = new Configuration();
-$conf = $configurationManager->getAll();
-
-$theme = $configurationManager->get('theme');
-
-//Instanciation du template
-$tpl = new RainTPL();
-//Definition des dossiers de template
-raintpl::configure("base_url", null );
-raintpl::configure("tpl_dir", './templates/'.$theme.'/' );
-raintpl::configure("cache_dir", "./cache/tmp/" );
-
-$resultUpdate = Update::ExecutePatch();
-
-$userManager = new User();
-$myUser = (isset($_SESSION['currentUser'])?unserialize($_SESSION['currentUser']):false);
-if (empty($myUser)) {
-    /* Pas d'utilisateur dans la session ?
-     * On tente de récupérer une nouvelle session avec un jeton. */
-    $myUser = User::existAuthToken();
-    $_SESSION['currentUser'] = serialize($myUser);
-}
-
-$feedManager = new Feed();
-$eventManager = new Event();
-$folderManager = new Folder();
-
-// Sélection de la langue de l'interface utilisateur
-if (!$myUser) {
-    $languages = Translation::getHttpAcceptLanguages();
-} else {
-    $languages = array($configurationManager->get('language'));
-}
-
-i18n_init($languages, dirname(__FILE__).'/templates/'.$theme.'/');
-if ($resultUpdate) die (_t('LEED_UPDATE_MESSAGE'));
-
-$view = '';
-$tpl->assign('myUser',$myUser);
-$tpl->assign('feedManager',$feedManager);
-$tpl->assign('eventManager',$eventManager);
-$tpl->assign('userManager',$userManager);
-$tpl->assign('folderManager',$folderManager);
-$tpl->assign('configurationManager',$configurationManager);
-$tpl->assign('synchronisationCode',$configurationManager->get('synchronisationCode'));
-
-$articleDisplayAnonymous = $configurationManager->get('articleDisplayAnonymous');
-$tpl->assign('articleDisplayAnonymous',$articleDisplayAnonymous);
-
-$isAlwaysDisplayed = ($articleDisplayAnonymous=='1') || ($myUser!=false);
-$tpl->assign('isAlwaysDisplayed',$isAlwaysDisplayed);
-
-//Récuperation et sécurisation de toutes les variables POST et GET
-$_ = array();
-foreach(array_merge($_POST, $_GET) as $key => $val){
-    if(is_string($val)) {
-        $_[$key] = Functions::secure($val, 2); // on ne veut pas d'addslashes
-    }
-}
-
-$tpl->assign('_',$_);
-$tpl->assign('action','');
-
-//Inclusion des plugins
-Plugin::includeAll();
-// pour inclure aussi les traductions des plugins dans les js
-$tpl->assign('i18n_js',$i18n_js);
-
-?>
diff --git a/leed/footer.php b/leed/footer.php
deleted file mode 100644
index 6f752eb402a2687c8785a9b3dd18730e63237900..0000000000000000000000000000000000000000
--- a/leed/footer.php
+++ /dev/null
@@ -1,5 +0,0 @@
-<?php
-
-$tpl->assign('executionTime',number_format(microtime(true)-$start,3));
-$html = $tpl->draw($view);
-?>
\ No newline at end of file
diff --git a/leed/header.php b/leed/header.php
deleted file mode 100644
index fa4beec19a3d3c0b57cc1e44422940dbafb03643..0000000000000000000000000000000000000000
--- a/leed/header.php
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-if(!file_exists('constant.php')) {
-    header('location: install.php');
-    exit();
-}
-require_once('common.php');
-
-?>
diff --git a/leed/humans.txt b/leed/humans.txt
deleted file mode 100644
index a74b3235e4c25a95902b5ec49caa01e05cf23db7..0000000000000000000000000000000000000000
--- a/leed/humans.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-/* the humans responsible & colophon */
-/* humanstxt.org */
-
-
-/* TEAM */
-  Creator: Idleman (http://blog.idleman.fr)
-  Contributors: Sbgodin (http://sbgodin.fr)
-                Simounet (contact@simounet.net)
-                Alef-Burzmali (thomas.fargeix@burzmali.com)
-                Cobalt74 (http://www.cobestran.com)
-  Site: http://blog.idleman.fr
-  Twitter: none
-  Location: Nowhere
-
-/* THANKS */
-  Names (& URL): BoilerPlate, Modernizr, jQuery, Initializr, PHP authors & chuck norris
-
-/* SITE */
-  Standards: HTML5, CSS3
-  Components: Modernizr, jQuery
-  Software: Sublime Text2
diff --git a/leed/i18n.php b/leed/i18n.php
deleted file mode 100644
index 480838275435ac32efeaa2acc41d2e1aa080b5f0..0000000000000000000000000000000000000000
--- a/leed/i18n.php
+++ /dev/null
@@ -1,165 +0,0 @@
-<?php
-
-/*
- @nom: i18n
- @auteur: Idleman (http://blog.idleman.fr)
- @description:  Fonctions de gestion de la traduction
- */
-
-class Translation {
-
-    // Répertoire contenant les traductions
-    const LOCALE_DIR = 'locale';
-
-    /* Langue utilisée si aucune langue n'est demandée ou si les langues
-     * demandées ne sont pas disponibles. Idem pour les traductions.*/
-    const DEFAULT_LANGUAGE = 'fr';
-
-    // tableau associatif des traductions
-    var $trans = array();
-    var $language = ''; // langue courante
-    var $translatedLanguages = array(); // langues traduites
-
-    /** @param location L'endroit où se trouve le dossier 'locale'
-     *  @param languages Les langues demandées */
-    function __construct($location, $languages=array()) {
-        $this->location = $location;
-        if (!is_array($languages)) $languages = array($languages);
-        $this->translatedLanguages = $this->listLanguages();
-        $languages[]=self::DEFAULT_LANGUAGE;
-        $this->languages = $languages;
-        foreach ($languages as $language) {
-            if (empty($language)) continue;
-            if ($this->load($language)) {
-                $this->language = $language;
-                break;
-            }
-        }
-    }
-
-    /* @return la liste des langues avec une traduction */
-    protected function listLanguages() {
-        $translatedLanguages = array();
-        $files = glob($this->location.'/'.self::LOCALE_DIR.'/*.json');
-        if (is_array($files)) {
-            foreach($files as $file){
-                preg_match('/([a-z]{2})\.json$/', $file, $matches);
-                $hasLocale = !empty($matches);
-                assert($hasLocale);
-                $translatedLanguages [] = $matches[1];
-            }
-        }
-        return $translatedLanguages;
-    }
-
-    /* Charge la traduction
-     * @param language la langue sélectionnée
-     * @return TRUE si le chargement s'est bien fait, FALSE sinon */
-    protected function load($language) {
-        if (!preg_match('/^[a-z]{2}$/', $language)) {
-            error_log("Invalid language: '$language'");
-            return false;
-        }
-        $trans = $this->loadFile($language);
-        if (empty($trans)) return false;
-        $isLanguageKnown = in_array($language, $this->translatedLanguages);
-        assert($isLanguageKnown);
-        if ($language!=self::DEFAULT_LANGUAGE) {
-            $defaultTrans = $this->loadFile(self::DEFAULT_LANGUAGE);
-            $hasDefaultTrans = !empty($defaultTrans);
-            assert($hasDefaultTrans);
-            $trans = array_merge($defaultTrans, $trans);
-        }
-        $this->trans = $trans;
-        return true;
-    }
-
-    /* Charge un fichier
-     * @param $language Le fichier de langue concerné
-     * @return Tableau associatif contenant les traductions */
-    protected function loadFile($language) {
-        $fileName = $this->location.'/'.self::LOCALE_DIR.'/'.$language.'.json';
-        $content = @file_get_contents($fileName);
-        if (empty($content)) {
-            $translations = array();
-        } else {
-            $translations = json_decode($content, true);
-            foreach ($translations as $id => $translation) {
-                if (empty($translation)) {
-                    # Retire les traductions vides afin qu'elles soient
-                    # traduites dans une autre langue si possible.
-                    unset($translations[$id]);
-                }
-            }
-
-            if (!empty($content) && empty($translations))
-                error_log("Error while loading '$fileName'");
-        }
-        return $translations;
-    }
-
-    /* Retourne la traduction et substitue les variables.
-     * get('TEST_TRANS', array('4'))
-     * Retournera 'Nombre : 4' si TEST_TRANS == 'Nombre : $1' */
-    function get($key, $args=array()) {
-        if (isset($this->trans[$key])&&!empty($this->trans[$key])) {
-            $value = $this->trans[$key];
-            for($i=0;$i<count($args);$i++){
-                $value = str_replace('$'.($i+1), $args[$i], $value);
-            }
-        } else {
-            $value = $key;
-        }
-        return $value;
-    }
-
-    /* Ajoute une traduction à la suite de celle-ci.
-     * Note : il faudra appeler getJson() si nécessaire */
-    function append(Translation $other) {
-        $this->trans = array_merge($this->trans, $other->trans);
-    }
-
-    /* @return la version Json des traductions */
-    function getJson() {
-        return json_encode($this->trans);
-    }
-
-    /* @return un tableau des langues préférées */
-    static function getHttpAcceptLanguages() {
-        /** Exemple de directive :
-         * eo,fr;q=0.8,fr-FR;q=0.6,en-US;q=0.4,en;q=0.2
-         * Les langues sont séparées entre elles par des virgules.
-         * Chaque langue est séparée du coefficient, si présent, par un point-virgule.
-         */
-        $httpAcceptLanguage = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ?
-            $_SERVER['HTTP_ACCEPT_LANGUAGE'] : self::DEFAULT_LANGUAGE;
-        $languageList = array();
-        foreach (explode(',', $httpAcceptLanguage) as $language) {
-            $languageList[] = substr($language, 0, 2); // fr-FR;q=0.6 --> fr
-        }
-        return array_unique($languageList); // en-US,en-UK --> en, en --> en
-    }
-
-}
-
-// Initialise le singleton, avec les langues possibles
-function i18n_init($languages, $location){
-    global $i18n,$i18n_js;
-    if (!isset($i18n)) {
-        // Charge d'abord les traductions de base
-        $i18n = new Translation(dirname(__FILE__), $languages);
-        // Charge ensuite la traduction demandée (celle du thème courant)
-        $i18n->append(new Translation($location, $languages));
-        $i18n_js = $i18n->getJson();
-    }
-    return $i18n->language;
-}
-
-// Appel rapide de la traduction
-function _t($key,$args=array(),$debug=false){
-    global $i18n;
-    return $i18n->get($key, $args);
-}
-
-
-?>
diff --git a/leed/index.php b/leed/index.php
deleted file mode 100644
index 708fb74b82b5ae6dc17634f187db1d83192acaa3..0000000000000000000000000000000000000000
--- a/leed/index.php
+++ /dev/null
@@ -1,172 +0,0 @@
-<?php
-
-/*
- @nom: index
- @auteur: Idleman (http://blog.idleman.fr)
- @description:  Page d'accueil et de lecture des flux
-*/
-
-require_once('header.php');
-
-
-Plugin::callHook("index_pre_treatment", array(&$_));
-
-//Récuperation de l'action (affichage) demandée
-$action = (isset($_['action'])?$_['action']:'');
-$tpl->assign('action',$action);
-if($isAlwaysDisplayed) {
-    //Récuperation des dossiers de flux par ordre de nom
-    $tpl->assign('folders',$folderManager->populate('name'));
-    //Recuperation de tous les non Lu
-    $tpl->assign('unread',$feedManager->countUnreadEvents());
-    //recuperation de tous les flux
-    $allFeeds = $feedManager->getFeedsPerFolder();
-    $tpl->assign('allFeeds',$allFeeds);
-    //recuperation de tous les flux par dossier
-    $tpl->assign('allFeedsPerFolder',$allFeeds['folderMap']);
-    //recuperation de tous les event nons lu par dossiers
-    $tpl->assign('allEvents',$eventManager->getEventCountPerFolder());
-    //utilisé pour récupérer le statut d'un feed dans le template (en erreur ou ok)
-    $feedState = new Feed();
-    $tpl->assign('feedState',$feedState);
-}
-//afficher ou non le champ OTP
-$tpl->assign('otpEnabled', $configurationManager->get('otpEnabled'));
-
-$articleDisplayAuthor = $configurationManager->get('articleDisplayAuthor');
-$articleDisplayDate = $configurationManager->get('articleDisplayDate');
-$articleDisplayFolderSort = $configurationManager->get('articleDisplayFolderSort');
-$articleDisplayHomeSort = $configurationManager->get('articleDisplayHomeSort');
-$articleDisplayLink = $configurationManager->get('articleDisplayLink');
-$articleDisplayMode = $configurationManager->get('articleDisplayMode');
-$articlePerPages = (int) $configurationManager->get('articlePerPages');
-$displayOnlyUnreadFeedFolder = $configurationManager->get('displayOnlyUnreadFeedFolder');
-if (!isset($displayOnlyUnreadFeedFolder)) $displayOnlyUnreadFeedFolder=false;
-($displayOnlyUnreadFeedFolder=='true')?$displayOnlyUnreadFeedFolder_reverse='false':$displayOnlyUnreadFeedFolder_reverse='true';
-$optionFeedIsVerbose = $configurationManager->get('optionFeedIsVerbose');
-
-$page = isset($_['page']) && (int) $_['page'] > 1 ? (int) $_['page'] : 1;
-$startArticle = ($page - 1) * $articlePerPages;
-$numberOfItem= 0;
-
-$tpl->assign('articleDisplayAuthor',$articleDisplayAuthor);
-$tpl->assign('articleDisplayDate',$articleDisplayDate);
-$tpl->assign('articleDisplayFolderSort',$articleDisplayFolderSort);
-$tpl->assign('articleDisplayHomeSort',$articleDisplayHomeSort);
-$tpl->assign('articleDisplayLink',$articleDisplayLink);
-$tpl->assign('articleDisplayMode',$articleDisplayMode);
-$tpl->assign('articlePerPages',$articlePerPages);
-$tpl->assign('displayOnlyUnreadFeedFolder',$displayOnlyUnreadFeedFolder);
-$tpl->assign('displayOnlyUnreadFeedFolder_reverse',$displayOnlyUnreadFeedFolder_reverse);
-
-$target = '`'.MYSQL_PREFIX.'event`.`title`,`'.MYSQL_PREFIX.'event`.`unread`,`'.MYSQL_PREFIX.'event`.`favorite`,`'.MYSQL_PREFIX.'event`.`feed`,';
-if($articleDisplayMode=='summary') $target .= '`'.MYSQL_PREFIX.'event`.`description`,';
-if($articleDisplayMode=='content') $target .= '`'.MYSQL_PREFIX.'event`.`content`,';
-if($articleDisplayLink) $target .= '`'.MYSQL_PREFIX.'event`.`link`,';
-if($articleDisplayDate) $target .= '`'.MYSQL_PREFIX.'event`.`pubdate`,';
-if($articleDisplayAuthor) $target .= '`'.MYSQL_PREFIX.'event`.`creator`,';
-$target .= '`'.MYSQL_PREFIX.'event`.`id`';
-
-$tpl->assign('target',$target);
-$tpl->assign('feeds',[]);
-$tpl->assign('order','');
-$tpl->assign('unreadEventsForFolder',0);
-$pagesArray = array();
-
-switch($action){
-    /* AFFICHAGE DES EVENEMENTS D'UN FLUX EN PARTICULIER */
-    case 'selectedFeed':
-        $currentFeed = $feedManager->getById($_['feed']);
-        if(!is_object($currentFeed)) {
-            header('location: ./');
-            exit;
-        }
-        $tpl->assign('currentFeed',$currentFeed);
-        $numberOfItem = $eventManager->rowCount(array('feed'=>$currentFeed->getId()));
-        $allowedOrder = array(
-            'date' => 'pubdate DESC',
-            'older' => 'pubdate',
-            'unread' => 'unread DESC,pubdate DESC'
-        );
-        $orderKey = isset($_['order']) && array_key_exists($_['order'], $allowedOrder) ?
-            $_['order'] : 'unread';
-        $order = $allowedOrder[$orderKey];
-        $events = $currentFeed->getEvents($order,$startArticle,$articlePerPages,$target);
-
-        $tpl->assign('order', $orderKey);
-
-    break;
-    /* AFFICHAGE DES EVENEMENTS D'UN DOSSIER EN PARTICULIER */
-    case 'selectedFolder':
-        $currentFolder = $folderManager->getById($_['folder']);
-        if(!is_object($currentFolder)) {
-            header('location: ./');
-            exit;
-        }
-        $tpl->assign('currentFolder',$currentFolder);
-        $numberOfItem = $currentFolder->unreadCount();
-        if($articleDisplayFolderSort) {$order = '`'.MYSQL_PREFIX.'event`.`pubdate` desc';} else {$order = '`'.MYSQL_PREFIX.'event`.`pubdate` asc';}
-        $events = $currentFolder->getEvents($order,$startArticle,$articlePerPages,$target);
-
-
-    break;
-    /* AFFICHAGE DES EVENEMENTS FAVORIS */
-    case 'favorites':
-        $numberOfItem = $eventManager->rowCount(array('favorite'=>1));
-        $events = $eventManager->loadAllOnlyColumn($target,array('favorite'=>1),'pubdate DESC',$startArticle.','.$articlePerPages);
-        $tpl->assign('numberOfItem',$numberOfItem);
-    break;
-
-    /* AFFICHAGE DES EVENEMENTS NON LUS (COMPORTEMENT PAR DEFAUT) */
-    case 'unreadEvents':
-    case 'wrongLogin':
-        $wrongLogin = true;
-    default:
-        $wrongLogin = !empty($wrongLogin);
-        $tpl->assign('wrongLogin',$wrongLogin);
-        if(!$isAlwaysDisplayed) {
-            break;
-        }
-        $filter = array('unread'=>1);
-        if($optionFeedIsVerbose) {
-            $numberOfItem = $eventManager->rowCount($filter);
-        } else {
-            $numberOfItem = $eventManager->getEventCountNotVerboseFeed();
-        }
-        if($articleDisplayHomeSort) {$order = 'pubdate desc';} else {$order = 'pubdate asc';}
-        if($optionFeedIsVerbose) {
-            $events = $eventManager->loadAllOnlyColumn($target,$filter,$order,$startArticle.','.$articlePerPages);
-        } else {
-            $events = $eventManager->getEventsNotVerboseFeed($order,$startArticle,$articlePerPages,$target);
-        }
-        $tpl->assign('numberOfItem',$numberOfItem);
-
-    break;
-}
-$pages = ceil($numberOfItem/$articlePerPages);
-$tpl->assign('pages',$pages);
-$tpl->assign('page',$page);
-
-$paginationScale = $configurationManager->get('paginationScale');
-if (empty($paginationScale)) {
-    $configurationManager->put('paginationScale', 5);
-    $paginationScale = $configurationManager->get('paginationScale');
-}
-
-for($i=($page-$paginationScale<=0?1:$page-$paginationScale);$i<($page+$paginationScale>$pages+1?$pages+1:$page+$paginationScale);$i++){
-    $pagesArray[]=$i;
-}
-$tpl->assign('pagesArray',$pagesArray);
-$tpl->assign('previousPages',($page-$paginationScale<0?-1:$page-$paginationScale-1));
-$tpl->assign('nextPages',($page+$paginationScale>$pages+1?-1:$page+$paginationScale));
-
-
-Plugin::callHook("index_post_treatment", array(&$events));
-$tpl->assign('events',$events);
-$tpl->assign('time',$_SERVER['REQUEST_TIME']);
-$tpl->assign('hightlighted',0);
-$tpl->assign('scroll',false);
-
-$view = 'index';
-require_once('footer.php');
-?>
diff --git a/leed/install.php b/leed/install.php
deleted file mode 100644
index 16e7625b0b91cef087dc745ba3a5af896871d6c3..0000000000000000000000000000000000000000
--- a/leed/install.php
+++ /dev/null
@@ -1,249 +0,0 @@
-<?php
-
-/*
- @nom: install
- @auteur: Idleman (http://blog.idleman.fr)
- @description:  Page d'installation du script (a supprimer après installation)
- */
-
-require_once('Functions.class.php');
-require_once('Install.class.php');
-require_once('i18n.php');
-global $i18n;
-$install = new Install();
-
-/* Prend le choix de langue de l'utilisateur, soit :
- * - lorsqu'il vient de changer la langue du sélecteur ($lang)
- * - lorsqu'il vient de lancer l'installeur ($install_changeLngLeed)
- */
-$lang = '';
-if (isset($_GET['lang'])) $lang = $_GET['lang'];
-elseif (isset($_POST['install_changeLngLeed'])) $lang = $_POST['install_changeLngLeed'];
-
-$installDirectory = dirname(__FILE__).'/install';
-
-// N'affiche que les langues du navigateur
-// @TODO: il faut afficher toutes les langues disponibles
-//        avec le choix par défaut de la langue préférée
-$languageList = Translation::getHttpAcceptLanguages();
-if (!empty($lang)) {
-    // L'utilisateur a choisi une langue, qu'on incorpore dans la liste
-    array_unshift($languageList, $lang);
-    $liste = array_unique($languageList);
-}
-unset($i18n); //@TODO: gérer un singleton et le choix de langue / liste de langue
-$currentLanguage = i18n_init($languageList, $installDirectory);
-
-$languageList = array_unique($i18n->languages);
-
-if (file_exists('constant.php')) {
-    die(_t('ALREADY_INSTALLED'));
-}
-
-define('DEFAULT_TEMPLATE', 'marigolds');
-$templates = scandir('templates');
-if (!in_array(DEFAULT_TEMPLATE, $templates)) die('Missing default template : '.DEFAULT_TEMPLATE);
-$templates = array_diff($templates, array(DEFAULT_TEMPLATE, '.', '..')); // Répertoires non voulus sous Linux
-sort($templates);
-$templates = array_merge(array(DEFAULT_TEMPLATE), $templates); // le thème par défaut en premier
-
-// Cookie de la session
-$cookiedir = '';
-if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/';
-session_set_cookie_params(0, $cookiedir);
-session_start();
-
-// Protection des variables
-$_ = array_merge($_GET, $_POST);
-$installActionName = 'installButton';
-$install->launch($_, $installActionName);
-
-?>
-<!doctype html>
-<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="<?php echo $currentLanguage;?>"> <![endif]-->
-<!--[if IE 7]>    <html class="no-js lt-ie9 lt-ie8" lang="<?php echo $currentLanguage;?>"> <![endif]-->
-<!--[if IE 8]>    <html class="no-js lt-ie9" lang="<?php echo $currentLanguage;?>"> <![endif]-->
-<!--[if gt IE 8]><!--> <html class="no-js" lang="<?php echo $currentLanguage;?>"> <!--<![endif]-->
-<head>
-    <meta charset="utf-8">
-    <meta name="referrer" content="no-referrer" />
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-    <title><?php echo _t('INSTALL_TITLE') ?></title>
-    <meta name="viewport" content="width=device-width">
-    <link rel="stylesheet" href="templates/marigolds/css/style.css">
-    <style>
-        code {
-            color:#000;
-            font-size: 1em;
-        }
-        .install h1 {
-            margin-bottom: 1.3em;
-        }
-        .install h2 {
-            margin-bottom: 0.1em;
-            font-size: 1.5em;
-        }
-        .install ul {
-            margin: 0;
-            padding: 0;
-        }
-        .install li {
-            list-style: none outside none;
-        }
-        .install span {
-            display: inline-block;
-            width: 8em;
-            padding-right: 1em;
-        }
-        button#installButton {
-            margin-top: 1em;
-            font-size: 2em;
-        }
-        .message {
-            color: #ffffff;
-            margin-bottom: 2em;
-        }
-        .message li {
-            border:1px solid #212121
-        }
-        .messageError {
-            background-color: #F16529;
-        }
-        .messageSuccess {
-            background-color: #008000;
-        }
-    </style>
-</head>
-<body>
-<div class="global-wrapper">
-    <div id="header-container">
-        <header class="wrapper clearfix">
-            <h1 class="logo" id="title"><a href="./">L<i>eed</i></a></h1>
-            <nav>
-            </nav>
-        </header>
-    </div>
-    <?php
-    if ($install->getFinished()){
-        echo '<div id="main-container">
-                <div id="main" class="wrapper clearfix">
-                    <div id="menuBar"></div>
-                        <h1>'._t('INSTALL_TITLE_END').'</h1>
-                        <span>'._t('INSTALL_END').'</span>
-                        <hr>
-                        <button id="installButton" name="<?php echo $installActionName; ?>" onclick="document.location.href=\'settings.php#preferenceBloc\'">'._t('INSTALL_BTN_END').'</button>
-              ';
-        // écriture des balises de fin et ne pas faire la suite
-        echo '</div>
-            <div id="footer-container">
-                <footer class="wrapper">
-                    <p>Leed "Light Feed" by <a target="_blank" rel="noopener noreferrer" href="http://blog.idleman.fr">Idleman</a></p>
-                </footer>
-            </div>
-            </body>
-            </html>';
-        exit();
-    }
-
-
-    ?>
-    <div id="main-container">
-        <div id="main" class="wrapper clearfix">
-        <div id="menuBar">
-        <aside>
-            <h3 class="left"><?php echo _t('INSTALL_PRE_REQUIS') ?></h3>
-            <ul class="clear" style="margin:0">
-            <?php
-                foreach($install->logs as $type => $messages){
-                    if(empty($messages)) {
-                        continue;
-                    }
-                    $class = 'message ';
-                    $class .= $type === 'errors' ? 'messageError':'messageSuccess';
-                    $label = $type === 'errors' ? _t('ERROR') : _t('SUCCESS');
-                    echo "<li class='$class'>$label&nbsp;:<ul>";
-
-                    foreach ($messages as $message){
-                        echo "<li>$message</li>";
-                    }
-                    echo "</ul></li>";
-                }
-            ?>
-            </ul>
-        </aside>
-    </div>
-    <form action="install.php" method="POST" class="install">
-        <h1><?php echo _t('INSTALL_TITLE') ?></h1>
-        <h2><?php echo _t('INSTALL_TAB_GENERAL') ?></h2>
-        <ul>
-            <li>
-                <span><?php echo _t('INSTALL_LANGUAGE') ?></span>
-                <select name="install_changeLngLeed" onchange="window.location.href='install.php?lang='+this[this.selectedIndex].value">
-                <?php
-                    foreach($languageList as $lang){
-                        $sel = $lang==$currentLanguage?'selected=selected':'';
-                        echo "<option $sel value='$lang'>$lang</option>";
-                    }
-                ?>
-                </select>
-            </li>
-            <li>
-                <span><?php echo _t('INSTALL_TEMPLATE') ?></span>
-                <?php
-                    $disabled = count($templates)<2 ? "disabled" : "";
-                    echo "<select name='template' $disabled>\n";
-                    foreach($templates as $name){
-                        echo "<option value='$name'>$name</option>";
-                    }
-                ?>
-                </select>
-            </li>
-            <li>
-                <span><?php echo _t('PROJECT_ROOT') ?></span>
-                <input type="text" name="root" value="<?php echo $install->getDefaultRoot(); ?>">
-            </li>
-        </ul>
-        <h2><?php echo _t('INSTALL_TAB_BDD') ?></h2>
-        <ul>
-            <li>
-                <span><?php echo _t('INSTALL_HOST') ?></span>
-                <input type="text" name="mysqlHost" value="<?php echo $install->options['db']['mysqlHost']; ?>" placeholder="<?php echo _t('INSTALL_COMMENT_HOST') ?>">
-            </li>
-            <li>
-                <span><?php echo _t('LOGIN') ?></span>
-                <input type="text" name="mysqlLogin" value="<?php echo $install->options['db']['mysqlLogin']; ?>">
-            </li>
-            <li>
-                <span><?php echo _t('PASSWORD') ?></span>
-                <input type="text" autocomplete="off" name="mysqlMdp" value="<?php echo $install->options['db']['mysqlMdp']; ?>" placeholder="<?php echo _t('INSTALL_DISPLAY_CLEAR') ?>">
-            </li>
-            <li>
-                <span><?php echo _t('INSTALL_BDD') ?></span>
-                <input type="text" name="mysqlBase" value="<?php echo $install->options['db']['mysqlBase']; ?>" placeholder="<?php echo _t('INSTALL_COMMENT_BDD') ?>">
-            </li>
-            <li>
-                <span><?php echo _t('INSTALL_PREFIX_TABLE') ?></span>
-                <input type="text" name="mysqlPrefix" value="<?php echo $install->options['db']['mysqlPrefix']; ?>">
-            </li>
-        </ul>
-        <h2><?php echo _t('INSTALL_TAB_ADMIN') ?></h2>
-        <ul>
-            <li>
-                <span><?php echo _t('LOGIN') ?></span>
-                <input type="text" name="login" value="<?php echo $install->options['user']['login']; ?>" placeholder="<?php echo _t('LOGIN') ?>">
-            </li>
-            <li>
-                <span><?php echo _t('PASSWORD') ?></span>
-                <input type="text" autocomplete="off" name="password" value="<?php echo $install->options['user']['password']; ?>" placeholder="<?php echo _t('INSTALL_DISPLAY_CLEAR') ?>">
-            </li>
-        </ul>
-        <button id="installButton" name="<?php echo $installActionName; ?>"><?php echo _t('INSTALL_BTN') ?></button>
-    </form>
-</div>
-<div id="footer-container">
-    <footer class="wrapper">
-        <p>Leed "Light Feed" by <a target="_blank" rel="noopener noreferrer" href="http://blog.idleman.fr">Idleman</a></p>
-    </footer>
-</div>
-</body>
-</html>
diff --git a/leed/locale/en.json b/leed/locale/en.json
deleted file mode 100755
index 7ea3b0754bf522cef03fdfd629a0a8464afa5ad2..0000000000000000000000000000000000000000
--- a/leed/locale/en.json
+++ /dev/null
@@ -1,85 +0,0 @@
-{
- "ALREADY_INSTALLED":"Leed is already configured. Delete or rename the configuration file.",
- "AT_TOTAL":"in total",
- "BROWSER_AUDIO_ELEMENT_NOT_SUPPORTED": "Your browser does not support the audio element.",
- "BROWSER_VIDEO_ELEMENT_NOT_SUPPORTED": "Your browser does not support the video element.",
- "CLIC_HERE_SYNC_IMPORT":"Click here to synchronize your imported feeds.",
- "ERROR":"Errors",
- "ERRORS":"error(s)",
- "FEED_ALREADY_STORED": "Feed already stored.",
- "FORMAT_DATE_HOURS":"m.d.Y \\a\\t h:i:s A",
- "FULL_SYNCHRONISATION":"Complete synchronization…",
- "GENERAL_FOLDER":"General",
- "GOOD":"good",
- "GRADUATE_SYNCHRONISATION":"Graduated synchronization",
- "IMPORT":"Import",
- "IMPORT_COFFEE_TIME":"NB : the import can take time, leave your browser do the job and go grab a coffee :).",
- "IMPORT_ERROR":"Errors during the import!",
- "IMPORT_FEED_ALREADY_KNOWN":"Some feeds were alreadw known, they were not imported again",
- "IMPORT_NO_PROBLEM":"Import successfuly done.",
- "INSTALL_BDD":"Base",
- "INSTALL_BTN":"Start the installation",
- "INSTALL_BTN_END":"Access to my Leed",
- "INSTALL_COMMENT_BDD":"(to be created before)",
- "INSTALL_COMMENT_HOST":"(Generally 'localhost')",
- "INSTALL_DISPLAY_CLEAR":"(will be displayed in clear)",
- "INSTALL_END":"You can customize your installation through many plugins available <a target='_blank' rel='noopener noreferrer' href='https://github.com/Leed-market'>Leed-market</a>.",
- "INSTALL_ERROR_CONNEXION":"Unable to connect to database",
- "INSTALL_ERROR_CURL":"The required function 'curl_exec' is inaccessible on your server, please install the Curl module for PHP.",
- "INSTALL_ERROR_DB_INFOS":"The 'host', 'username' and 'base' fields about your database are required.",
- "INSTALL_ERROR_FILEGET":"The required function 'file_get_contents' is inaccessible on your server, check your version of PHP.",
- "INSTALL_ERROR_FILEPUT":"The required 'file_put_contents' is inaccessible on your server, check your version of PHP.",
- "INSTALL_ERROR_GD":"The required 'gd_info' is inaccessible on your server, check your version of PHP.",
- "INSTALL_ERROR_MB":"The required 'mb_internal_encoding' is inaccessible on your server, check your version of PHP.",
- "INSTALL_ERROR_MYSQLICONNECT":"The required function 'mysqli_connect' is inaccessible on your server, check your MySql installation.",
- "INSTALL_ERROR_PHPV":"Your PHP version ($1) is too old, it is possible that some features script include malfunctions.",
- "INSTALL_ERROR_PHPXML":"The required 'simplexml_load_file' is inaccessible on your server, check your version of PHP.",
- "INSTALL_ERROR_RIGHT":"Can't write in Leed directory, please add write permissions on the entire folder (sudo chmod 777 -R $1, think about shielding permissions later)",
- "INSTALL_ERROR_SAFEMODE":"The script can not manage the timeout alone because your safe mode is enabled,<br/>in your PHP configuration file, set the max_execution_time variable to 0 or disable safemode.",
- "INSTALL_ERROR_USERPWD":"For safety, it is necessary to provide a user name and password.",
- "INSTALL_HOST":"Host",
- "INSTALL_INFO_CONNEXION":"Connecting to the database : OK",
- "INSTALL_INFO_CURL":"Requested function 'curl_exec' : OK",
- "INSTALL_INFO_FILEGET":"Requested function 'file_get_contents' : OK",
- "INSTALL_INFO_FILEPUT":"Requested function 'file_put_contents' : OK",
- "INSTALL_INFO_GD":"Requested function 'gd_info' : OK",
- "INSTALL_INFO_MB":"Requested function 'mb_internal_encoding' : OK",
- "INSTALL_INFO_MYSQLICONNECT":"Requested function 'mysqli_connect' : OK",
- "INSTALL_INFO_PHPV":"Php version compatibility ($1) : OK",
- "INSTALL_INFO_PHPXML":"Requested function 'simplexml_load_file' : OK",
- "INSTALL_INFO_RIGHT":"Permissions on the current folder: OK ",
- "INSTALL_INFO_SAFEMODE":"Management timeout: OK",
- "INSTALL_LANGUAGE":"Language",
- "INSTALL_PREFIX_TABLE":"Table prefix",
- "INSTALL_PRE_REQUIS":"Prerequisites for installation",
- "INSTALL_TAB_ADMIN":"Administrator",
- "INSTALL_TAB_BDD":"Database",
- "INSTALL_TAB_GENERAL":"General",
- "INSTALL_TEMPLATE":"Template",
- "INSTALL_TITLE":"Installing Leed",
- "INSTALL_TITLE_END":"Leed Installation Complete!",
- "LEED_UPDATE_MESSAGE":"Leed has been updated. Refresh the page to return to your Leed.",
- "LOGIN":"Username",
- "NEW_ARTICLES":"new articles",
- "OPML_FILE":"OPML File",
- "PASSWORD":"Password",
- "PENDING":"In progress...",
- "PROJECT_ROOT":"Project root",
- "PUBDATE_WITHINSTANT":"the $1",
- "PUBDATE_WITHINSTANT_LOWERH1":"$1 min ago",
- "PUBDATE_WITHINSTANT_LOWERH24":"$1 h and $2 min ago",
- "SECONDS":"secondes",
- "SUCCESS":"Success",
- "SYNCHRONISATION_COMPLETE":"Synchronization finished.",
- "SYNCHRONISATION_TYPE":"Synchronization type",
- "SYNCHRONIZE_COFFEE_TIME":"NB : The synchronization can take time, leave your browser do the job and go grab a coffee :).",
- "SYNCHRONIZE_NOW":"Synchronize now",
- "USER_ADD_DUPLICATE":"A user with this login already exists. Please use another one.",
- "USER_ADD_MISSING_LOGIN":"The login field can't be empty.",
- "USER_ADD_MISSING_PASSWORD":"The password field can't be empty.",
- "USER_ADD_OK":"User added.",
- "USER_DEL_MISSING_ID":"Something went wrong: the user id is missing.",
- "USER_DEL_OK":"User removed.",
- "USER_DEL_UNKNOWN_ID":"Something went wrong: the user id is unknown",
- "YOU_MUST_BE_CONNECTED_ACTION":"You must be logged in for this action."
-}
diff --git a/leed/locale/eo.json b/leed/locale/eo.json
deleted file mode 100755
index 9d3aca77eeb76c78f39865aa66b2c7cbf1dbcf91..0000000000000000000000000000000000000000
--- a/leed/locale/eo.json
+++ /dev/null
@@ -1,85 +0,0 @@
-{
- "ALREADY_INSTALLED":"Leed estas jam agordita. Forviŝu aû alinomu la dosieron agordan.",
- "AT_TOTAL":"Sume",
- "BROWSER_AUDIO_ELEMENT_NOT_SUPPORTED":"Via retumilo ne apogas la sonan elementon.",
- "BROWSER_VIDEO_ELEMENT_NOT_SUPPORTED":"Via retumilo ne apogas la videan elementon.",
- "CLIC_HERE_SYNC_IMPORT":"klaku tie por sinkroni viajn fluojn enportitajn.",
- "ERROR":"Eraro",
- "ERRORS":"eraro(j)",
- "FEED_ALREADY_STORED":"Fluo jam stokita.",
- "FORMAT_DATE_HOURS":"d/m/Y, H:i:s",
- "FULL_SYNCHRONISATION":"Sinkrono kompleta…",
- "GENERAL_FOLDER":"Äœenerala",
- "GOOD":"bona(j)",
- "GRADUATE_SYNCHRONISATION":"Sinkrono poioma",
- "IMPORT":"Enporto",
- "IMPORT_COFFEE_TIME":"Nb: la importo povas iom daŭri, lasu vian retumilo ruliĝi kaj iru trinki kafon.&nbsp;:)",
- "IMPORT_ERROR":"Eraroj dum enportado!",
- "IMPORT_FEED_ALREADY_KNOWN":"Certaj fluoj estis jam konataj, ili ne estas reenportitaj",
- "IMPORT_NO_PROBLEM":"La enporto ruliĝis sen problemo.",
- "INSTALL_BDD":"Datumbazo",
- "INSTALL_BTN":"Startigi la instaladon",
- "INSTALL_BTN_END":"Aliri mian Leed",
- "INSTALL_COMMENT_BDD":"(je krei antaÅ­e)",
- "INSTALL_COMMENT_HOST":"(Äœenerale 'localhost')",
- "INSTALL_DISPLAY_CLEAR":"(estos afiŝita nekaŝe)",
- "INSTALL_END":"Vi povas adapti vian instalon danke al multaj kromaĵoj haveblaj ĉe <a target='_blank' rel='noopener noreferrer' href='https://github.com/Leed-market'>Leed-market</a>.",
- "INSTALL_ERROR_CONNEXION":"Konekto neebla al datumbazo.",
- "INSTALL_ERROR_CURL":"La funkcio nepra 'curl_exec' ne akceseblas ĉe via servilo, kontrolu vian version de PHP.",
- "INSTALL_ERROR_DB_INFOS":"La kampoj 'Gastiganto', 'salutnomo' kaj 'datumbazo' pri via datumbazo nepras.",
- "INSTALL_ERROR_FILEGET":"La funkcio nepra 'file_get_contents' ne akceseblas ĉe via servilo, kontrolu vian version de PHP.",
- "INSTALL_ERROR_FILEPUT":"La funkcio nepra 'file_put_contents' ne akceseblas ĉe via servilo, kontrolu vian version de PHP.",
- "INSTALL_ERROR_GD":"La funkcio nepra 'gd_info' ne akceseblas ĉe via servilo, kontrolu vian version de PHP.",
- "INSTALL_ERROR_MB":"La funkcio nepra 'mb_internal_encoding' ne akceseblas ĉe via servilo, kontrolu vian version de PHP.",
- "INSTALL_ERROR_MYSQLICONNECT":"La funkcio nepra 'mysqli_connect' ne akceseblas ĉe via servilo, kontrolu vian version de MySql.",
- "INSTALL_ERROR_PHPV":"Via versio de PHP ($1) estas tro malnova, eblas ke funkcioj misfunkcias.",
- "INSTALL_ERROR_PHPXML":"La funkcio nepra 'simplexml_load_file' ne akceseblas ĉe via servilo, kontrolu vian version de PHP.",
- "INSTALL_ERROR_RIGHT":"Ne eblas skribi en la dosierujon Leed, bonvolu aldoni permesojn por skribi sur la tuta dosierujo (sudo chmod 777 -R $1, pripensu finagordi la permesoj poste)",
- "INSTALL_ERROR_SAFEMODE":"La skripto ne povas mastrumi la tempolimo mem ĉar via safe mode estas aktivita en via agorda dosiero de PHP, ŝalti la variablon max_execution_time al 0 aŭ malŝalti la safemode.",
- "INSTALL_ERROR_USERPWD":"Pro sekureco, necesas provizi uzantnomon kaj pasvorton.",
- "INSTALL_HOST":"Gastiganto",
- "INSTALL_INFO_CONNEXION":"Konekto al datumbazo: bone",
- "INSTALL_INFO_CURL":"Funkcio nepra 'curl_exec': bone",
- "INSTALL_INFO_FILEGET":"Funkcio nepra 'file_get_contents': bone",
- "INSTALL_INFO_FILEPUT":"Funkcio nepra 'file_put_contents': bone",
- "INSTALL_INFO_GD":"Funkcio nepra 'gd_info': bone",
- "INSTALL_INFO_MB":"Funkcio nepra 'mb_internal_encoding': bone",
- "INSTALL_INFO_MYSQLICONNECT":"Funkcio nepra 'mysqli_connect': bone",
- "INSTALL_INFO_PHPV":"Kongrueco versio PHP ($1): bone",
- "INSTALL_INFO_PHPXML":"Funkcio nepra 'simplexml_load_file': bone",
- "INSTALL_INFO_RIGHT":"Permesoj sur aktuala dosierujo: bone",
- "INSTALL_INFO_SAFEMODE":"Mastrumo de tempolimo: bone",
- "INSTALL_LANGUAGE":"Lingvo",
- "INSTALL_PREFIX_TABLE":"Prefikso (tabloj)",
- "INSTALL_PRE_REQUIS":"Postuloj por instalo",
- "INSTALL_TAB_ADMIN":"Administranto",
- "INSTALL_TAB_BDD":"Datumbazo",
- "INSTALL_TAB_GENERAL":"Ĝeneralaĵoj",
- "INSTALL_TEMPLATE":"Åœablono",
- "INSTALL_TITLE":"Instalado de Leed",
- "INSTALL_TITLE_END":"Instalado de Leed finita!",
- "LEED_UPDATE_MESSAGE":"Leed estis ĝisdatigita. Reŝargi la paĝon por reiri al via Leed.",
- "LOGIN":"Salutnomo",
- "NEW_ARTICLES":"Novaj artikoloj",
- "OPML_FILE":"Dosiero OPML",
- "PASSWORD":"Pasvorto",
- "PENDING":"Okazonta...",
- "PROJECT_ROOT":"Radiko projekta",
- "PUBDATE_WITHINSTANT":"je $1",
- "PUBDATE_WITHINSTANT_LOWERH1":"antaÅ­ $1 min",
- "PUBDATE_WITHINSTANT_LOWERH24":"antaÅ­ $1 h kaj $2 min",
- "SECONDS":"sekundoj",
- "SUCCESS":"Sukceso",
- "SYNCHRONISATION_COMPLETE":"Sinkronado finita.",
- "SYNCHRONISATION_TYPE":"tipo de sinkrono",
- "SYNCHRONIZE_COFFEE_TIME":"NB: La sinkronado povas daûri iom, lasu vian retumilon funkcii kaj iru trinki kafon.&nbsp;:)",
- "SYNCHRONIZE_NOW":"Sinkroni nun",
- "USER_ADD_DUPLICATE":"Uzanto kun tiu salutnomo jam ekzistas. Bonvolu uzi alian.",
- "USER_ADD_MISSING_LOGIN":"La salutnoma kampo ne estu malplena.",
- "USER_ADD_MISSING_PASSWORD":"La pasvorta kampo ne estu malplena.",
- "USER_ADD_OK":"Uzanto aldonita.",
- "USER_DEL_MISSING_ID":"Io malbone okazis: la uzanta id forestas.",
- "USER_DEL_OK":"Uzanto forviŝita.",
- "USER_DEL_UNKNOWN_ID":"Io malbone okazis: la uzanta id nekonatas.",
- "YOU_MUST_BE_CONNECTED_ACTION":"Vi devas esti ensalutita por fari tiun agon."
-}
diff --git a/leed/locale/es.json b/leed/locale/es.json
deleted file mode 100755
index 9456d7779dcad53011b7a2daffb040655b29e758..0000000000000000000000000000000000000000
--- a/leed/locale/es.json
+++ /dev/null
@@ -1,85 +0,0 @@
-{
- "ALREADY_INSTALLED":"Leed ya está configurado. Suprimir o renombrar el archivo de configuración.",
- "AT_TOTAL":"en total",
- "BROWSER_AUDIO_ELEMENT_NOT_SUPPORTED": "Tu navegador no implementa el elemento audio",
- "BROWSER_VIDEO_ELEMENT_NOT_SUPPORTED": "Tu navegador no implementa el elemento video",
- "CLIC_HERE_SYNC_IMPORT":"Haz clic aquí para actualisar los RSS importados.",
- "ERROR":"Errores",
- "ERRORS":"error(es)",
- "FEED_ALREADY_STORED": "Fuente ya presente.",
- "FORMAT_DATE_HOURS":"d/m/Y à H:i:s",
- "FULL_SYNCHRONISATION":"Syncronización completa…",
- "GENERAL_FOLDER":"General",
- "GOOD":"bueno(s)",
- "GRADUATE_SYNCHRONISATION":"Syncronización gradual",
- "IMPORT":"Importación",
- "IMPORT_COFFEE_TIME":"NB : La importación puede tomar cierto tiempo, deje su navegador y vaya tomarse un cafe.&nbsp;:)",
- "IMPORT_ERROR":"Errores durante la importación !",
- "IMPORT_FEED_ALREADY_KNOWN":"Algunos RSS ya estaban conocidos, no fueron importados",
- "IMPORT_NO_PROBLEM":"La importación se ha pasado sin problema.",
- "INSTALL_BDD":"Base",
- "INSTALL_BTN":"Empezar la instalación",
- "INSTALL_BTN_END":"Ir a mi Leed",
- "INSTALL_COMMENT_BDD":"(crearlo antes)",
- "INSTALL_COMMENT_HOST":"(En general 'localhost')",
- "INSTALL_DISPLAY_CLEAR":"(no va a ser escrito cifrado en el campo)",
- "INSTALL_END":"Puede personalizar su instancia gracias a numerosos complementos que son disponibles sobre el <a target='_blank' rel='noopener noreferrer' href='https://github.com/Leed-market'>Leed-market</a>.",
- "INSTALL_ERROR_CONNEXION":"No se puede conectar a la base de datos.",
- "INSTALL_ERROR_CURL":"Se necesita la función 'curl_exec' pero no es disponible sobre el servidor. Por favor, instale el módulo Curl por PHP.",
- "INSTALL_ERROR_DB_INFOS":"Se necesitan los campos 'huésped', 'login' y 'base' en cuanto a vuestra base de datos.",
- "INSTALL_ERROR_FILEGET":"Se necesita la función 'file_get_contents' pero no es disponible sobre el servidor. Verificar su versión de PHP.",
- "INSTALL_ERROR_FILEPUT":"Se necesita la función 'file_put_contents' pero no es disponible sobre el servidor. Verificar su versión de PHP.",
- "INSTALL_ERROR_GD":"Se necesita la función 'gd_info' pero no es disponible sobre el servidor. Verificar su versión de PHP.",
- "INSTALL_ERROR_MB":"Se necesita la función 'mb_internal_encoding' pero no es disponible sobre el servidor. Verificar su versión de PHP.",
- "INSTALL_ERROR_MYSQLICONNECT":"Se necesita la función 'mysqli_connect' pero no es disponible sobre el servidor. Verificar su versión de PHP.",
- "INSTALL_ERROR_PHPV":"Su versión de PHP ($1) es demasiada antigua, se puede que algunas funcionalidades del script no funcionan.",
- "INSTALL_ERROR_PHPXML":"Se necesita la función 'simplexml_load_file' pero no es disponible sobre el servidor. Verificar su versión de PHP.",
- "INSTALL_ERROR_RIGHT":"No se puede escribir en el directorio de Leed. Añadir los permisos para escribir sobre todo el directorio (sudo chmod 777 -R $1, pensar a modificarlo de nuevo por medida se seguridad después de la instalación)",
- "INSTALL_ERROR_SAFEMODE":"El script no puede administrar el timeout solo ya que el safe mode está activado,<br/> en su archivo de configuración de PHP, poner la variable max_execution_time a 0 o desactivar el safe mode.",
- "INSTALL_ERROR_USERPWD":"Por medida de seguridad, es necesario que proporzione un login y una contraseña.",
- "INSTALL_HOST":"Huésped",
- "INSTALL_INFO_CONNEXION":"Connexión a la base de datos : OK",
- "INSTALL_INFO_CURL":"Función necesaria 'curl_exec' : OK",
- "INSTALL_INFO_FILEGET":"Función necesaria 'file_get_contents' : OK",
- "INSTALL_INFO_FILEPUT":"Función necesaria 'file_put_contents' : OK",
- "INSTALL_INFO_GD":"Función necesaria 'gd_info' : OK",
- "INSTALL_INFO_MB":"Función necesaria 'mb_internal_encoding' : OK",
- "INSTALL_INFO_MYSQLICONNECT":"Función necesaria 'mysqli_connect' : OK",
- "INSTALL_INFO_PHPV":"Version de PHP ($1) compatible : OK",
- "INSTALL_INFO_PHPXML":"Función necesaria 'simplexml_load_file' : OK",
- "INSTALL_INFO_RIGHT":"Permisos sobre el directorio corriente : OK",
- "INSTALL_INFO_SAFEMODE":"Gestión del timeout : OK",
- "INSTALL_LANGUAGE":"Idioma",
- "INSTALL_PREFIX_TABLE":"Prefijo de las tablas",
- "INSTALL_PRE_REQUIS":"Prerequisito para la instalación",
- "INSTALL_TAB_ADMIN":"Administrador",
- "INSTALL_TAB_BDD":"Base de datos",
- "INSTALL_TAB_GENERAL":"General",
- "INSTALL_TEMPLATE":"Tema",
- "INSTALL_TITLE":"Instalación de Leed",
- "INSTALL_TITLE_END":"Instalación de Leed terminada !",
- "LEED_UPDATE_MESSAGE":"Se ha actualizado Leed. Actualizar la página para volver a Leed.",
- "LOGIN":"Login",
- "NEW_ARTICLES":"nuevas publicaciónes",
- "OPML_FILE":"Archivo OPML",
- "PASSWORD":"Contraseña",
- "PENDING":"En curso…",
- "PROJECT_ROOT":"Raíz del proyecto",
- "PUBDATE_WITHINSTANT":"la $1",
- "PUBDATE_WITHINSTANT_LOWERH1":"hace $1 min",
- "PUBDATE_WITHINSTANT_LOWERH24":"hace $1 h y $2 min",
- "SECONDS":"segundos",
- "SUCCESS":"Éxito",
- "SYNCHRONISATION_COMPLETE":"Syncronisación terminada.",
- "SYNCHRONISATION_TYPE":"Tipo de syncronisación",
- "SYNCHRONIZE_COFFEE_TIME":"NB : La syncronisación puede tomar cierto tiempo, deje su navegador y vaya tomarse un cafe.&nbsp;:)",
- "SYNCHRONIZE_NOW":"Syncronisar ahora",
- "USER_ADD_DUPLICATE":"Ya existe un usuario con ese nombre.",
- "USER_ADD_MISSING_LOGIN":"El campo usuario no puede estar vacío.",
- "USER_ADD_MISSING_PASSWORD":"El campo contraseña no puede estar vacío. ",
- "USER_ADD_OK":"Usuario añadido.",
- "USER_DEL_MISSING_ID":"Algo salió mal : id del usuario está vacío.",
- "USER_DEL_OK":"Usuario suprimido.",
- "USER_DEL_UNKNOWN_ID":"Algo salió mal : nombre de usuario desconocido.",
- "YOU_MUST_BE_CONNECTED_ACTION":"Usted debe haber iniciado una sesión para continuar."
-}
diff --git a/leed/locale/fr.json b/leed/locale/fr.json
deleted file mode 100755
index ff9eed254507e1143c95988edf814f22c0ec4dab..0000000000000000000000000000000000000000
--- a/leed/locale/fr.json
+++ /dev/null
@@ -1,85 +0,0 @@
-{
- "ALREADY_INSTALLED":"Leed est déjà configuré. Supprimez ou renommez le fichier de configuration.",
- "AT_TOTAL":"au total",
- "BROWSER_AUDIO_ELEMENT_NOT_SUPPORTED": "Votre navigateur ne gère pas l'élément audio",
- "BROWSER_VIDEO_ELEMENT_NOT_SUPPORTED": "Votre navigateur ne gère pas l'élément video",
- "CLIC_HERE_SYNC_IMPORT":"Cliquez ici pour synchroniser vos flux importés.",
- "ERROR":"Erreurs",
- "ERRORS":"erreur(s)",
- "FEED_ALREADY_STORED": "Flux déjà présent.",
- "FORMAT_DATE_HOURS":"d/m/Y à H:i:s",
- "FULL_SYNCHRONISATION":"Synchronisation complète…",
- "GENERAL_FOLDER":"Générale",
- "GOOD":"bon(s)",
- "GRADUATE_SYNCHRONISATION":"Synchronisation graduée",
- "IMPORT":"Import",
- "IMPORT_COFFEE_TIME":"NB : L’import peut prendre un certain temps, laissez votre navigateur tourner et allez vous prendre un café.&nbsp;:)",
- "IMPORT_ERROR":"Erreurs durant l’import !",
- "IMPORT_FEED_ALREADY_KNOWN":"Certains flux étaient déjà connus, ils n’ont pas été réimportés",
- "IMPORT_NO_PROBLEM":"L’import s’est déroulé sans problème.",
- "INSTALL_BDD":"Base",
- "INSTALL_BTN":"Lancer l'installation",
- "INSTALL_BTN_END":"Accéder à mon Leed",
- "INSTALL_COMMENT_BDD":"(à créer avant)",
- "INSTALL_COMMENT_HOST":"(Généralement 'localhost')",
- "INSTALL_DISPLAY_CLEAR":"(sera affiché en clair)",
- "INSTALL_END":"Vous pouvez personnaliser votre installation grâce à de nombreux plugins disponibles sur <a target='_blank' rel='noopener noreferrer' href='https://github.com/Leed-market'>Leed-market</a>.",
- "INSTALL_ERROR_CONNEXION":"Connexion impossible à la base de données.",
- "INSTALL_ERROR_CURL":"La fonction requise 'curl_exec' est inaccessible sur votre serveur, veuillez installer le module Curl de PHP.",
- "INSTALL_ERROR_DB_INFOS":"Les champs 'hôte', 'identifiant' et 'base' concernant votre base de données sont requis.",
- "INSTALL_ERROR_FILEGET":"La fonction requise 'file_get_contents' est inaccessible sur votre serveur, vérifiez votre version de PHP.",
- "INSTALL_ERROR_FILEPUT":"La fonction requise 'file_put_contents' est inaccessible sur votre serveur, vérifiez votre version de PHP.",
- "INSTALL_ERROR_GD":"La fonction requise 'gd_info' est inaccessible sur votre serveur, vérifiez votre version de PHP.",
- "INSTALL_ERROR_MB":"La fonction requise 'mb_internal_encoding' est inaccessible sur votre serveur, vérifiez votre version de PHP.",
- "INSTALL_ERROR_MYSQLICONNECT":"La fonction requise 'mysqli_connect' est inaccessible sur votre serveur, vérifiez votre installation de MySql.",
- "INSTALL_ERROR_PHPV":"Votre version de PHP ($1) est trop ancienne, il est possible que certaines fonctionnalités du script comportent des dysfonctionnements.",
- "INSTALL_ERROR_PHPXML":"La fonction requise 'simplexml_load_file' est inaccessible sur votre serveur, vérifiez votre version de PHP.",
- "INSTALL_ERROR_RIGHT":"Écriture impossible dans le répertoire Leed, veuillez ajouter les permissions en écriture sur tout le dossier (sudo chmod 777 -R $1, pensez à blinder les permissions par la suite)",
- "INSTALL_ERROR_SAFEMODE":"Le script ne peut pas gérer le timeout tout seul car votre safe mode est activé,<br/> dans votre fichier de configuration PHP, mettez la variable max_execution_time à 0 ou désactivez le safemode.",
- "INSTALL_ERROR_USERPWD":"Par sécurité, il est nécessaire de fournir un nom d'utilisateur et un mot de passe.",
- "INSTALL_HOST":"Hôte",
- "INSTALL_INFO_CONNEXION":"Connexion à la base de données : OK",
- "INSTALL_INFO_CURL":"Fonction requise 'curl_exec' : OK",
- "INSTALL_INFO_FILEGET":"Fonction requise 'file_get_contents' : OK",
- "INSTALL_INFO_FILEPUT":"Fonction requise 'file_put_contents' : OK",
- "INSTALL_INFO_GD":"Fonction requise 'gd_info' : OK",
- "INSTALL_INFO_MB":"Fonction requise 'mb_internal_encoding' : OK",
- "INSTALL_INFO_MYSQLICONNECT":"Fonction requise 'mysqli_connect' : OK",
- "INSTALL_INFO_PHPV":"Compatibilité version PHP ($1) : OK",
- "INSTALL_INFO_PHPXML":"Fonction requise 'simplexml_load_file' : OK",
- "INSTALL_INFO_RIGHT":"Permissions sur le dossier courant : OK",
- "INSTALL_INFO_SAFEMODE":"Gestion du timeout : OK",
- "INSTALL_LANGUAGE":"Langue",
- "INSTALL_PREFIX_TABLE":"Préfixe des tables",
- "INSTALL_PRE_REQUIS":"Pré-requis à l'installation",
- "INSTALL_TAB_ADMIN":"Administrateur",
- "INSTALL_TAB_BDD":"Base de données",
- "INSTALL_TAB_GENERAL":"Général",
- "INSTALL_TEMPLATE":"Thème",
- "INSTALL_TITLE":"Installation de Leed",
- "INSTALL_TITLE_END":"Installation de Leed terminée !",
- "LEED_UPDATE_MESSAGE":"Leed a été mis à jour. Rafraîchir la page pour retourner sur votre Leed.",
- "LOGIN":"Identifiant",
- "NEW_ARTICLES":"nouveaux articles",
- "OPML_FILE":"Fichier OPML",
- "PASSWORD":"Mot de passe",
- "PENDING":"En cours…",
- "PROJECT_ROOT":"Racine du projet",
- "PUBDATE_WITHINSTANT":"le $1",
- "PUBDATE_WITHINSTANT_LOWERH1":"il y a $1 min",
- "PUBDATE_WITHINSTANT_LOWERH24":"il y a $1 h et $2 min",
- "SECONDS":"secondes",
- "SUCCESS":"Succès",
- "SYNCHRONISATION_COMPLETE":"Synchronisation terminée.",
- "SYNCHRONISATION_TYPE":"Type de synchronisation",
- "SYNCHRONIZE_COFFEE_TIME":"NB : La synchronisation peut prendre un certain temps, laissez votre navigateur tourner et allez vous prendre un café.&nbsp;:)",
- "SYNCHRONIZE_NOW":"Synchroniser maintenant",
- "USER_ADD_DUPLICATE":"Un utilisateur possédant cet identifiant existe déjà. Merci d'en utiliser un autre.",
- "USER_ADD_MISSING_LOGIN":"Le champ de l'identifiant ne peut pas être vide.",
- "USER_ADD_MISSING_PASSWORD":"Le champ du mot de passe ne peut pas être vide.",
- "USER_ADD_OK":"Utilisateur ajouté.",
- "USER_DEL_MISSING_ID":"Quelque chose s'est mal passé : l'id de l'utilisateur est absent.",
- "USER_DEL_OK":"Utilisateur supprimé.",
- "USER_DEL_UNKNOWN_ID":"Quelque chose s'est mal passé : l'id de l'utilisateur est inconnu.",
- "YOU_MUST_BE_CONNECTED_ACTION":"Vous devez être connecté pour effectuer cette action."
-}
diff --git a/leed/locale/oc.json b/leed/locale/oc.json
deleted file mode 100755
index e26527051ed22ea8a52633d29c3d9fd51ab381ed..0000000000000000000000000000000000000000
--- a/leed/locale/oc.json
+++ /dev/null
@@ -1,85 +0,0 @@
-{
- "ALREADY_INSTALLED":"Leed es ja configurat. Suprimissètz o renommatz lo fichièr de configuracion.",
- "AT_TOTAL":"en total",
- "BROWSER_AUDIO_ELEMENT_NOT_SUPPORTED": "Vòstre navigador gerís pas l'element audio",
- "BROWSER_VIDEO_ELEMENT_NOT_SUPPORTED": "Vòstre navigador gerís pas l'element video",
- "CLIC_HERE_SYNC_IMPORT":"Clicatz aquí per sincronizar vòstres flux importats.",
- "ERROR":"Errors",
- "ERRORS":"error(s)",
- "FEED_ALREADY_STORED": "Flux ja present.",
- "FORMAT_DATE_HOURS":"d/m/Y a H:i:s",
- "FULL_SYNCHRONISATION":"Sincronization complèta…",
- "GENERAL_FOLDER":"Generala",
- "GOOD":"bon(s)",
- "GRADUATE_SYNCHRONISATION":"Sincronizacion graduada",
- "IMPORT":"Import",
- "IMPORT_COFFEE_TIME":"NB : L’importacion pòt trigar un moment, daissatz lo navigador virar e anatz prendre un cafè.&nbsp;:)",
- "IMPORT_ERROR":"Errors en important !",
- "IMPORT_FEED_ALREADY_KNOWN":"Unes flus èran ja coneguts, son pas estats importats de nòu",
- "IMPORT_NO_PROBLEM":"L’importacion s’es passada sens cap de problèma.",
- "INSTALL_BDD":"Basa",
- "INSTALL_BTN":"Lançar l’installacion",
- "INSTALL_BTN_END":"Accedir a mon Leed",
- "INSTALL_COMMENT_BDD":"(de crear abans)",
- "INSTALL_COMMENT_HOST":"(Generalament 'localhost')",
- "INSTALL_DISPLAY_CLEAR":"(serà mostrat en clar)",
- "INSTALL_END":"Podètz personalizar vòstra installacion gràcias a mantunas extensions disponiblas sus <a target='_blank' rel='noopener noreferrer' href='https://github.com/Leed-market'>Leed-market</a>.",
- "INSTALL_ERROR_CONNEXION":"Connexion impossibla a la basa de donadas.",
- "INSTALL_ERROR_CURL":"La foncion requesida 'curl_exec' es inaccessibla sul vòstre servidor, mercés d’installar lo modul Curl de PHP.",
- "INSTALL_ERROR_DB_INFOS":"Los camps 'òst', 'identificant' e 'basa' tocant vòstra basa de donadas son necessaris.",
- "INSTALL_ERROR_FILEGET":"La foncion requesida 'file_get_contents' es inaccessible sul vòstre servidor, verificatz vòstra version de PHP.",
- "INSTALL_ERROR_FILEPUT":"La foncion requesida 'file_put_contents' es inaccessibla sul vòstre servidor, verificatz vòstra version de PHP.",
- "INSTALL_ERROR_GD":"La foncion requesida 'gd_info' es inaccessibla sul vòstre servidor, verificatz vòstra version de PHP.",
- "INSTALL_ERROR_MB":"La foncion requesida 'mb_internal_encoding' es inaccessibla sul vòstre servidor, verificatz vòstra version de PHP.",
- "INSTALL_ERROR_MYSQLICONNECT":"La foncion requesida 'mysqli_connect' es inaccessibla sul vòstre servidor, verificatz vòstra installacion de MySql.",
- "INSTALL_ERROR_PHPV":"Vòstra version de PHP ($1) es tròp anciana, poriá arribar qu’unas foncionalitats del script foncione pas coma cal.",
- "INSTALL_ERROR_PHPXML":"La foncion requesida 'simplexml_load_file' es inaccessibla sul vòstre servidor, verificatz vòstra version de PHP.",
- "INSTALL_ERROR_RIGHT":"Escritura impossibla al repertòri Leed, mercés d’ajustar las permissions en escritura sus tot lo dorsièr (sudo chmod 777 -R $1, pensatz de blindar las permissions aprèp)",
- "INSTALL_ERROR_SAFEMODE":"Lo script pòt pas gerir solet lo timeout perque vòstre safe mòde es activat,<br/> dins vòstre fichièr de configuracion PHP, botatz la variable max_execution_time a 0 o desactivatz lo safemode.",
- "INSTALL_ERROR_USERPWD":"Per seguretat, cal fornir un nom d’utilizaire e un senhal.",
- "INSTALL_HOST":"Ã’st",
- "INSTALL_INFO_CONNEXION":"Connexion a la basa de donadas : OK",
- "INSTALL_INFO_CURL":"Foncion requesida 'curl_exec' : OK",
- "INSTALL_INFO_FILEGET":"Foncion requesida 'file_get_contents' : OK",
- "INSTALL_INFO_FILEPUT":"Foncion requesida 'file_put_contents' : OK",
- "INSTALL_INFO_GD":"Foncion requesida 'gd_info' : OK",
- "INSTALL_INFO_MB":"Foncion requesida 'mb_internal_encoding' : OK",
- "INSTALL_INFO_MYSQLICONNECT":"Foncion requesida 'mysqli_connect' : OK",
- "INSTALL_INFO_PHPV":"Compatibilitat version PHP ($1) : OK",
- "INSTALL_INFO_RIGHT":"Permissions sul dorsièr actual : OK",
- "INSTALL_INFO_PHPXML":"Foncion requesida 'simplexml_load_file' : OK",
- "INSTALL_INFO_SAFEMODE":"Gestion del timeout : OK",
- "INSTALL_LANGUAGE":"Lenga",
- "INSTALL_PREFIX_TABLE":"Prefixe de las taulas",
- "INSTALL_PRE_REQUIS":"Pre-requesit a l’installacion",
- "INSTALL_TAB_ADMIN":"Administrator",
- "INSTALL_TAB_BDD":"Basa de donadas",
- "INSTALL_TAB_GENERAL":"General",
- "INSTALL_TEMPLATE":"Tèma",
- "INSTALL_TITLE":"Installacion de Leed",
- "INSTALL_TITLE_END":"Installacion de Leed acabada !",
- "LEED_UPDATE_MESSAGE":"Leed es estat actualizat. Tornatz cargar la pagina per tornar al vòstre Leed.",
- "LOGIN":"Identificant",
- "NEW_ARTICLES":"articles novèls",
- "OPML_FILE":"Fichièr OPML",
- "PASSWORD":"Senhal",
- "PENDING":"En cors…",
- "PROJECT_ROOT":"Raiç del projècte",
- "PUBDATE_WITHINSTANT":"lo $1",
- "PUBDATE_WITHINSTANT_LOWERH1":"fa $1 min",
- "PUBDATE_WITHINSTANT_LOWERH24":"fa $1 h e $2 min",
- "SECONDS":"segondas",
- "SUCCESS":"Succès",
- "SYNCHRONISATION_COMPLETE":"Sincronizacion acabada.",
- "SYNCHRONISATION_TYPE":"Tipe de sincronizacion",
- "SYNCHRONIZE_COFFEE_TIME":"NB : la sincronizacion pòt trigar un moment, daissatz lo navigador virar e anatz prendre un cafè.&nbsp;:)",
- "SYNCHRONIZE_NOW":"Sincronizar ara",
- "USER_ADD_DUPLICATE":"Un utilizaire amb aqueste identificant existís ja. Mercés de ne causir un autre.",
- "USER_ADD_MISSING_LOGIN":"Lo camp de l’identificant pòt pas èsser void.",
- "USER_ADD_MISSING_PASSWORD":"Lo camp del senhal pòt pas èsser void.",
- "USER_ADD_OK":"Utilizaire ajustat.",
- "USER_DEL_MISSING_ID":"Quicòm s’es mal passat : l’id de l’utilizaire es absent.",
- "USER_DEL_OK":"Utilizaire suprimit.",
- "USER_DEL_UNKNOWN_ID":"Quicòm s’es mal passat : l’id de l’utilizaire es desconegut.",
- "YOU_MUST_BE_CONNECTED_ACTION":"Devètz èsser connectat per realizar aquesta accion."
-}
diff --git a/leed/locale/zh.json b/leed/locale/zh.json
deleted file mode 100644
index 3092d7ba49adec1b8a02779340b9f108707041df..0000000000000000000000000000000000000000
--- a/leed/locale/zh.json
+++ /dev/null
@@ -1,85 +0,0 @@
-{
- "ALREADY_INSTALLED":"Leed已安装完成,请删除或更名安装文件",
- "AT_TOTAL":"总计",
- "BROWSER_AUDIO_ELEMENT_NOT_SUPPORTED": "你的浏览器不支持此音频播放。",
- "BROWSER_VIDEO_ELEMENT_NOT_SUPPORTED": "你的浏览器不支持此视频播放。",
- "CLIC_HERE_SYNC_IMPORT":"点击此处同步你导入的feeds.",
- "ERROR":"错误",
- "ERRORS":"错误",
- "FEED_ALREADY_STORED": "Feed已保存。",
- "FORMAT_DATE_HOURS":"Y.m.d h:i:s ",
- "FULL_SYNCHRONISATION":"完全同步…",
- "GENERAL_FOLDER":"通用",
- "GOOD":"可用",
- "GRADUATE_SYNCHRONISATION":"增量同步",
- "IMPORT":"导入",
- "IMPORT_COFFEE_TIME":"NB : 导入需要一些时间,你可以趁现在去泡杯茶 :).",
- "IMPORT_ERROR":"导入时发生错误!",
- "IMPORT_FEED_ALREADY_KNOWN":"部分Feed已存在,它们将不会被重复导入",
- "IMPORT_NO_PROBLEM":"导入成功完成。",
- "INSTALL_BDD":"数据库名",
- "INSTALL_BTN":"开始安装Leed",
- "INSTALL_BTN_END":"进入我的Leed",
- "INSTALL_COMMENT_BDD":"(需要提前建立)",
- "INSTALL_COMMENT_HOST":"(一般是 'localhost')",
- "INSTALL_DISPLAY_CLEAR":"(密码不会隐藏)",
- "INSTALL_END":"你可以通过大量插件来定制你的安装:<a target='_blank' rel='noopener noreferrer' href='https://github.com/Leed-market'>Leed-market</a>.",
- "INSTALL_ERROR_CONNEXION":"无法连接数据库",
- "INSTALL_ERROR_CURL":"需要的功能/组件 'curl_exec' 在您的服务器上不可用,请安装PHP的Curl模块。",
- "INSTALL_ERROR_DB_INFOS":"数据库服务器的地址、用户名和数据库名是必须的。",
- "INSTALL_ERROR_FILEGET":"需要的功能/组件 'file_get_contents' 在您的服务器上不可用,请检查PHP版本。",
- "INSTALL_ERROR_FILEPUT":"需要的功能/组件 'file_put_contents' 在您的服务器上不可用,请检查PHP版本。",
- "INSTALL_ERROR_GD":"需要的功能/组件 'gd_info' 在您的服务器上不可用,请检查PHP版本。",
- "INSTALL_ERROR_MB":"需要的功能/组件 'mb_internal_encoding' 在您的服务器上不可用,请检查PHP版本。",
- "INSTALL_ERROR_MYSQLICONNECT":"需要的功能/组件 'mysqli_connect' 在您的服务器上不可用,请检查您的Mysql安装。",
- "INSTALL_ERROR_PHPV":"您的PHP版本 ($1) 太低,将会影响部分功能的正常使用。",
- "INSTALL_ERROR_PHPXML":"需要的功能/组件 'simplexml_load_file' 在您的服务器上不可用,请检查PHP版本。",
- "INSTALL_ERROR_RIGHT":"Leed所在的目录不可写,请检查目录权限。 请给整个目录及子目录添加写权限 (运行命令 sudo chmod 777 -R $1, 稍后再考虑权限安全问题)",
- "INSTALL_ERROR_SAFEMODE":"由于你启用了safe mode,脚本无法单独管理超时。<br/>请在你的PHP配置文件中设置max_execution_time的值为0,或关闭safemode",
- "INSTALL_ERROR_USERPWD":"出于安全考虑,请务必设置一个用户名和密码。",
- "INSTALL_HOST":"数据库地址",
- "INSTALL_INFO_CONNEXION":"数据库连接 : 正常",
- "INSTALL_INFO_CURL":"所需功能/组件 'curl_exec' : 正常",
- "INSTALL_INFO_FILEGET":"所需功能/组件 'file_get_contents' : 正常",
- "INSTALL_INFO_FILEPUT":"所需功能/组件 'file_put_contents' : 正常",
- "INSTALL_INFO_GD":"所需功能/组件 'gd_info' : 正常",
- "INSTALL_INFO_MB":"所需功能/组件 'mb_internal_encoding' : 正常",
- "INSTALL_INFO_MYSQLICONNECT":"所需功能/组件 'mysqli_connect' : 正常",
- "INSTALL_INFO_PHPV":"PHP版本号: ($1) : 正常",
- "INSTALL_INFO_PHPXML":"所需功能/组件 'simplexml_load_file' : 正常",
- "INSTALL_INFO_RIGHT":"目录权限检查: 正常 ",
- "INSTALL_INFO_SAFEMODE":"管理超时检查: 正常",
- "INSTALL_LANGUAGE":"安装语言",
- "INSTALL_PREFIX_TABLE":"数据表前缀",
- "INSTALL_PRE_REQUIS":"安装前检查",
- "INSTALL_TAB_ADMIN":"管理员设置",
- "INSTALL_TAB_BDD":"数据库",
- "INSTALL_TAB_GENERAL":"通用设置",
- "INSTALL_TEMPLATE":"主题",
- "INSTALL_TITLE":"Leed安装",
- "INSTALL_TITLE_END":"Leed 安装完毕!",
- "LEED_UPDATE_MESSAGE":"Leed 已完成更新. 请刷新页面以回到你的Leed.",
- "LOGIN":"用户名",
- "NEW_ARTICLES":"新文章",
- "OPML_FILE":"OPML文件",
- "PASSWORD":"密码",
- "PENDING":"处理中...",
- "PROJECT_ROOT":"网站访问地址",
- "PUBDATE_WITHINSTANT":"the $1",
- "PUBDATE_WITHINSTANT_LOWERH1":"$1 分钟前",
- "PUBDATE_WITHINSTANT_LOWERH24":"$1 小时 $2 分钟前",
- "SECONDS":"秒",
- "SUCCESS":"成功",
- "SYNCHRONISATION_COMPLETE":"同步已结束。",
- "SYNCHRONISATION_TYPE":"同步类型",
- "SYNCHRONIZE_COFFEE_TIME":"NB : 同步需要一些时间,你可以趁现在去泡杯茶 :).",
- "SYNCHRONIZE_NOW":"立即同步",
- "USER_ADD_DUPLICATE":"该用户名已存在,请尝试另一个",
- "USER_ADD_MISSING_LOGIN":"必须提供用户名。",
- "USER_ADD_MISSING_PASSWORD":"必须提供密码。",
- "USER_ADD_OK":"用户已添加。",
- "USER_DEL_MISSING_ID":"发生错误:用户ID丢失",
- "USER_DEL_OK":"用户已删除。",
- "USER_DEL_UNKNOWN_ID":"发生错误:未知的用户ID",
- "YOU_MUST_BE_CONNECTED_ACTION":"你需要登录来完成此操作"
-}
diff --git a/leed/otphp/LICENCE b/leed/otphp/LICENCE
deleted file mode 100644
index d14cbc23ca01f5d7701f95f0207d461e3091d6a3..0000000000000000000000000000000000000000
--- a/leed/otphp/LICENCE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2011 Le Lag 
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
diff --git a/leed/otphp/README.markdown b/leed/otphp/README.markdown
deleted file mode 100644
index 11336ee72334d3d039193dc72a33761b3ce79fe5..0000000000000000000000000000000000000000
--- a/leed/otphp/README.markdown
+++ /dev/null
@@ -1,71 +0,0 @@
-# OTPHP - A PHP One Time Password Library
-
-A php library for generating one time passwords according to [ RFC 4226 ](http://tools.ietf.org/html/rfc4226) and the [ HOTP RFC ](http://tools.ietf.org/html/draft-mraihi-totp-timebased-00)
-
-This is compatible with Google Authenticator apps available for Android and iPhone, and now in use on GMail
-
-This is a port of the rotp ruby library available at https://github.com/mdp/rotp
-
-
-## Quick overview of using One Time Passwords on your phone
-
-* OTP's involve a shared secret, stored both on the phone and the server
-* OTP's can be generated on a phone without internet connectivity(AT&T mode)
-* OTP's should always be used as a second factor of authentication(if your phone is lost, you account is still secured with a password)
-* Google Authenticator allows you to store multiple OTP secrets and provision those using a QR Code(no more typing in the secret)
-
-## Installation
-
-   clone this repository and include lib/otphp.php in your project. 
-
-## Use
-
-### Time based OTP's
-
-    $totp = new \OTPHP\TOTP("base32secret3232");
-    $totp->now(); // => 492039
-
-    // OTP verified for current time
-    $totp->verify(492039); // => true
-    //30s later
-    $totp->verify(492039); // => false
-
-### Counter based OTP's
-
-    $hotp = new \OTPHP\HOTP("base32secretkey3232");
-    $hotp->at(0); // => 260182
-    $hotp->at(1); // => 55283
-    $hotp->at(1401); // => 316439
-
-    // OTP verified with a counter
-    $totp->verify(316439, 1401); // => true
-    $totp->verify(316439, 1402); // => false
-
-### Google Authenticator Compatible
-
-The library works with the Google Authenticator iPhone and Android app, and also
-includes the ability to generate provisioning URI's for use with the QR Code scanner
-built into the app.
-
-    $totp->provisioning_uri(); // => 'otpauth://totp/alice@google.com?secret=JBSWY3DPEHPK3PXP'
-    $hotp->provisioning_uri(); // => 'otpauth://hotp/alice@google.com?secret=JBSWY3DPEHPK3PXP&counter=0'
-
-This can then be rendered as a QR Code which can then be scanned and added to the users
-list of OTP credentials.
-
-#### Working example
-
-Scan the following barcode with your phone, using Google Authenticator
-
-![QR Code for OTP](http://chart.apis.google.com/chart?cht=qr&chs=250x250&chl=otpauth%3A%2F%2Ftotp%2Falice%40google.com%3Fsecret%3DJBSWY3DPEHPK3PXP)
-
-Now run the following and compare the output
-
-    <?php
-    require_once('otphp/lib/otphp.php');
-    $totp = new \OTPHP\TOTP("JBSWY3DPEHPK3PXP");
-    echo "Current OTP: ". $totp->now();
-
-## Licence
-
-This software is release under MIT licence.
diff --git a/leed/otphp/lib/hotp.php b/leed/otphp/lib/hotp.php
deleted file mode 100644
index 7092fd9ff1d87a6f1cb78591c6ab0a5b0074b3d9..0000000000000000000000000000000000000000
--- a/leed/otphp/lib/hotp.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-namespace OTPHP {
-  /**
-   * HOTP - One time password generator 
-   * 
-   * The HOTP class allow for the generation 
-   * and verification of one-time password using 
-   * the HOTP specified algorithm.
-   *
-   * This class is meant to be compatible with 
-   * Google Authenticator
-   *
-   * This class was originally ported from the rotp
-   * ruby library available at https://github.com/mdp/rotp
-   */
-  class HOTP extends OTP {
-    /**
-     *  Get the password for a specific counter value
-     *  @param integer $count the counter which is used to
-     *  seed the hmac hash function.
-     *  @return integer the One Time Password
-     */
-    public function at($count) {
-      return $this->generateOTP($count);
-    }
-
-
-    /**
-     * Verify if a password is valid for a specific counter value
-     *
-     * @param integer $otp the one-time password 
-     * @param integer $counter the counter value
-     * @return  bool true if the counter is valid, false otherwise
-     */
-    public function verify($otp, $counter) {
-      return ($otp == $this->at($counter));
-    }
-
-    /**
-     * Returns the uri for a specific secret for hotp method.
-     * Can be encoded as a image for simple configuration in 
-     * Google Authenticator.
-     *
-     * @param string $name the name of the account / profile
-     * @param integer $initial_count the initial counter 
-     * @return string the uri for the hmac secret
-     */
-    public function provisioning_uri($name, $initial_count) {
-      return "otpauth://hotp/".urlencode($name)."?secret={$this->secret}&counter=$initial_count";
-    }
-  }
-
-}
diff --git a/leed/otphp/lib/otp.php b/leed/otphp/lib/otp.php
deleted file mode 100644
index 77bcfe9716460593e482c6b2d84bf92f2692056d..0000000000000000000000000000000000000000
--- a/leed/otphp/lib/otp.php
+++ /dev/null
@@ -1,120 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-namespace OTPHP {
-/**
- * One Time Password Generator 
- * 
- * The OTP class allow the generation of one-time
- * password that is described in rfc 4xxx.
- * 
- * This is class is meant to be compatible with 
- * Google Authenticator.
- *
- * This class was originally ported from the rotp
- * ruby library available at https://github.com/mdp/rotp
- */
-class OTP {
-    /**
-     * The base32 encoded secret key
-     * @var string
-     */
-    public $secret;
-
-    /**
-     * The algorithm used for the hmac hash function
-     * @var string
-     */
-    public $digest;
-
-    /**
-     * The number of digits in the one-time password
-     * @var integer
-     */ 
-    public $digits;
-
-    /**
-     * Constructor for the OTP class
-     * @param string $secret the secret key
-     * @param array $opt options array can contain the
-     * following keys :
-     *   @param integer digits : the number of digits in the one time password
-     *   Currently Google Authenticator only support 6. Defaults to 6.
-     *   @param string digest : the algorithm used for the hmac hash function
-     *   Google Authenticator only support sha1. Defaults to sha1
-     *
-     * @return new OTP class.
-     */
-    public function __construct($secret, $opt = Array()) {
-      $this->digits = isset($opt['digits']) ? $opt['digits'] : 6;
-      $this->digest = isset($opt['digest']) ? $opt['digest'] : 'sha1';
-      $this->secret = $secret;
-    }
-
-    /**
-     * Generate a one-time password
-     *
-     * @param integer $input : number used to seed the hmac hash function.
-     * This number is usually a counter (HOTP) or calculated based on the current
-     * timestamp (see TOTP class).
-     * @return integer the one-time password 
-     */
-    public function generateOTP($input) {
-      $hash = hash_hmac($this->digest, $this->intToBytestring($input), $this->byteSecret());
-      foreach(str_split($hash, 2) as $hex) { // stupid PHP has bin2hex but no hex2bin WTF
-        $hmac[] = hexdec($hex);
-      }
-      $offset = $hmac[19] & 0xf;
-      $code = ($hmac[$offset+0] & 0x7F) << 24 |
-        ($hmac[$offset + 1] & 0xFF) << 16 |
-        ($hmac[$offset + 2] & 0xFF) << 8 |
-        ($hmac[$offset + 3] & 0xFF);
-      return $code % pow(10, $this->digits);
-    }
-
-    /**
-     * Returns the binary value of the base32 encoded secret
-     * @access private
-     * This method should be private but was left public for
-     * phpunit tests to work.
-     * @return binary secret key
-     */
-    public function byteSecret() {
-      return \Base32::decode($this->secret);
-    }
-
-    /**
-     * Turns an integer in a OATH bytestring
-     * @param integer $int
-     * @access private
-     * @return string bytestring
-     */
-    public function intToBytestring($int) {
-      $result = Array();
-      while($int != 0) {
-        $result[] = chr($int & 0xFF);
-        $int >>= 8;
-      }
-      return str_pad(join(array_reverse($result)), 8, "\000", STR_PAD_LEFT);
-    }
-  }
-}
diff --git a/leed/otphp/lib/otphp.php b/leed/otphp/lib/otphp.php
deleted file mode 100644
index a6c6f8d66b47ff44c20c0fa66d105f5d5dc703ff..0000000000000000000000000000000000000000
--- a/leed/otphp/lib/otphp.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__).'/../vendor/libs.php';
-require_once dirname(__FILE__).'/otp.php';
-require_once dirname(__FILE__).'/hotp.php';
-require_once dirname(__FILE__).'/totp.php';
-
diff --git a/leed/otphp/lib/totp.php b/leed/otphp/lib/totp.php
deleted file mode 100644
index 10a1f42f3e30372b7964b05d76d0639501b67988..0000000000000000000000000000000000000000
--- a/leed/otphp/lib/totp.php
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-namespace OTPHP {
-  /**
-   * TOTP - One time password generator 
-   * 
-   * The TOTP class allow for the generation 
-   * and verification of one-time password using 
-   * the TOTP specified algorithm.
-   *
-   * This class is meant to be compatible with 
-   * Google Authenticator
-   *
-   * This class was originally ported from the rotp
-   * ruby library available at https://github.com/mdp/rotp
-   */
-  class TOTP extends OTP {
-    /**
-     * The interval in seconds for a one-time password timeframe
-     * Defaults to 30
-     * @var integer
-     */
-    public $interval;
-
-    public function __construct($s, $opt = Array()) {
-      $this->interval = isset($opt['interval']) ? $opt['interval'] : 30;
-      parent::__construct($s, $opt);
-    }
-
-    /**
-     *  Get the password for a specific timestamp value 
-     *
-     *  @param integer $timestamp the timestamp which is timecoded and 
-     *  used to seed the hmac hash function.
-     *  @return integer the One Time Password
-     */
-    public function at($timestamp) {
-      return $this->generateOTP($this->timecode($timestamp));
-    }
-
-    /**
-     *  Get the password for the current timestamp value 
-     *
-     *  @return integer the current One Time Password
-     */
-    public function now() {
-      return $this->generateOTP($this->timecode(time()));
-    }
-
-    /**
-     * Verify if a password is valid for a specific counter value
-     *
-     * @param integer $otp the one-time password 
-     * @param integer $timestamp the timestamp for the a given time, defaults to current time.
-     * @return  bool true if the counter is valid, false otherwise
-     */
-    public function verify($otp, $timestamp = null) {
-      if($timestamp === null)
-        $timestamp = time();
-      return ($otp == $this->at($timestamp));
-    }
-
-    /**
-     * Returns the uri for a specific secret for totp method.
-     * Can be encoded as a image for simple configuration in 
-     * Google Authenticator.
-     *
-     * @param string $name the name of the account / profile
-     * @return string the uri for the hmac secret
-     */
-    public function provisioning_uri($name) {
-      return "otpauth://totp/".urlencode($name)."?secret={$this->secret}";
-    }
-
-    /**
-     * Transform a timestamp in a counter based on specified internal
-     *
-     * @param integer $timestamp
-     * @return integer the timecode
-     */
-    protected function timecode($timestamp) {
-      return (int)( (((int)$timestamp * 1000) / ($this->interval * 1000)));
-    }
-  }
-
-}
diff --git a/leed/otphp/tests/HOTPTest.php b/leed/otphp/tests/HOTPTest.php
deleted file mode 100644
index 4e0635e643996bd5873505ff5a8445f3e782b257..0000000000000000000000000000000000000000
--- a/leed/otphp/tests/HOTPTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__).'/../lib/otphp.php';
-
-class HOPTTest extends PHPUnit_Framework_TestCase {
-  public function test_it_gets_the_good_code() {
-    $o = new \OTPHP\HOTP('JDDK4U6G3BJLEZ7Y');
-    $this->assertEquals(855783,$o->at(0));
-    $this->assertEquals(549607,$o->at(500));
-    $this->assertEquals(654666,$o->at(1500));
-  }
-
-  public function test_it_verify_the_code() {
-    $o = new \OTPHP\HOTP('JDDK4U6G3BJLEZ7Y');
-    $this->assertTrue($o->verify(855783, 0));
-    $this->assertTrue($o->verify(549607, 500));
-    $this->assertTrue($o->verify(654666, 1500));
-  }
-
-  public function test_it_returns_the_provisioning_uri() {
-    $o = new \OTPHP\HOTP('JDDK4U6G3BJLEZ7Y');
-    $this->assertEquals("otpauth://hotp/name?secret=JDDK4U6G3BJLEZ7Y&counter=0",
-      $o->provisioning_uri('name', 0));
-  }
-}
diff --git a/leed/otphp/tests/OTPTest.php b/leed/otphp/tests/OTPTest.php
deleted file mode 100644
index bf5337e43e139c898be41bcf065a21acf588de8a..0000000000000000000000000000000000000000
--- a/leed/otphp/tests/OTPTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__).'/../lib/otphp.php';
-
-class TestOTP extends PHPUnit_Framework_TestCase {
-
-  public function test_it_decodes_the_secret() {
-    $o = new \OTPHP\OTP('JDDK4U6G3BJLEZ7Y');
-    $this->assertEquals("H\306\256S\306\330R\262g\370", $o->byteSecret());
-  }
-
-  public function test_it_turns_an_int_into_bytestring() {
-    $o = new \OTPHP\OTP('JDDK4U6G3BJLEZ7Y');
-    $this->assertEquals("\000\000\000\000\000\000\000\000", $o->intToBytestring(0));
-    $this->assertEquals("\000\000\000\000\000\000\000\001", $o->intToBytestring(1));
-    $this->assertEquals("\000\000\000\000\000\000\001\364", $o->intToBytestring(500));
-    $this->assertEquals("\000\000\000\000\000\000\005\334", $o->intToBytestring(1500));
-  }
-
-  public function test_it_generate_otp() {
-    $o = new \OTPHP\OTP('JDDK4U6G3BJLEZ7Y');
-    $this->assertEquals(855783, $o->generateOTP(0));
-    $this->assertEquals(549607, $o->generateOTP(500));
-    $this->assertEquals(654666, $o->generateOTP(1500));
-  }
-}
diff --git a/leed/otphp/tests/TOTPTest.php b/leed/otphp/tests/TOTPTest.php
deleted file mode 100644
index 34ad6d7c5ba1f1dcdd3f90b05fd72e38e9b570ba..0000000000000000000000000000000000000000
--- a/leed/otphp/tests/TOTPTest.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__).'/../lib/otphp.php';
-
-class TOPTTest extends PHPUnit_Framework_TestCase {
-
-  public function test_it_has_an_interval() {
-    $o = new \OTPHP\TOTP('JDDK4U6G3BJLEZ7Y');
-    $this->assertEquals(30,$o->interval);
-    $b = new \OTPHP\TOTP('JDDK4U6G3BJLEZ7Y', Array('interval'=>60));
-    $this->assertEquals(60,$b->interval);
-  }
-
-  public function test_it_gets_the_good_code_at_given_times() {
-    $o = new \OTPHP\TOTP('JDDK4U6G3BJLEZ7Y');
-    $this->assertEquals(855783,$o->at(0));
-    $this->assertEquals(762124,$o->at(319690800));
-    $this->assertEquals(139664,$o->at(1301012137));
-  }
-
-  public function test_it_verify_the_code() {
-    $o = new \OTPHP\TOTP('JDDK4U6G3BJLEZ7Y');
-    $this->assertTrue($o->verify(855783, 0));
-    $this->assertTrue($o->verify(762124, 319690800));
-    $this->assertTrue($o->verify(139664, 1301012137));
-  }
-
-  public function test_it_returns_the_provisioning_uri() {
-    $o = new \OTPHP\TOTP('JDDK4U6G3BJLEZ7Y');
-    $this->assertEquals("otpauth://totp/name?secret=JDDK4U6G3BJLEZ7Y",
-      $o->provisioning_uri('name'));
-  }
-}
diff --git a/leed/otphp/tests/TestTest.php b/leed/otphp/tests/TestTest.php
deleted file mode 100644
index 5f776f804d10c4f2c39e9167b875b23503b5b02b..0000000000000000000000000000000000000000
--- a/leed/otphp/tests/TestTest.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__).'/../lib/otphp.php';
-
-class TestTest extends PHPUnit_Framework_TestCase {
-  public function testThatPHPUnitWorks() {
-    $this->assertEquals(1,1);
-  }
-}
diff --git a/leed/otphp/vendor/base32.php b/leed/otphp/vendor/base32.php
deleted file mode 100644
index b17722d16f2510c98d9932bb964160fc2923edd8..0000000000000000000000000000000000000000
--- a/leed/otphp/vendor/base32.php
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-
-/**
- * Encode in Base32 based on RFC 4648.
- * Requires 20% more space than base64  
- * Great for case-insensitive filesystems like Windows and URL's  (except for = char which can be excluded using the pad option for urls)
- *
- * @package default
- * @author Bryan Ruiz
- **/
-class Base32 {
-
-   private static $map = array(
-        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', //  7
-        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
-        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
-        'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
-        '='  // padding char
-    );
-    
-   private static $flippedMap = array(
-        'A'=>'0', 'B'=>'1', 'C'=>'2', 'D'=>'3', 'E'=>'4', 'F'=>'5', 'G'=>'6', 'H'=>'7',
-        'I'=>'8', 'J'=>'9', 'K'=>'10', 'L'=>'11', 'M'=>'12', 'N'=>'13', 'O'=>'14', 'P'=>'15',
-        'Q'=>'16', 'R'=>'17', 'S'=>'18', 'T'=>'19', 'U'=>'20', 'V'=>'21', 'W'=>'22', 'X'=>'23',
-        'Y'=>'24', 'Z'=>'25', '2'=>'26', '3'=>'27', '4'=>'28', '5'=>'29', '6'=>'30', '7'=>'31'
-    );
-    
-    /**
-     *    Use padding false when encoding for urls
-     *
-     * @return base32 encoded string
-     * @author Bryan Ruiz
-     **/
-    public static function encode($input, $padding = true) {
-        if(empty($input)) return "";
-        $input = str_split($input);
-        $binaryString = "";
-        for($i = 0; $i < count($input); $i++) {
-            $binaryString .= str_pad(base_convert(ord($input[$i]), 10, 2), 8, '0', STR_PAD_LEFT);
-        }
-        $fiveBitBinaryArray = str_split($binaryString, 5);
-        $base32 = "";
-        $i=0;
-        while($i < count($fiveBitBinaryArray)) {    
-            $base32 .= self::$map[base_convert(str_pad($fiveBitBinaryArray[$i], 5,'0'), 2, 10)];
-            $i++;
-        }
-        if($padding && ($x = strlen($binaryString) % 40) != 0) {
-            if($x == 8) $base32 .= str_repeat(self::$map[32], 6);
-            else if($x == 16) $base32 .= str_repeat(self::$map[32], 4);
-            else if($x == 24) $base32 .= str_repeat(self::$map[32], 3);
-            else if($x == 32) $base32 .= self::$map[32];
-        }
-        return $base32;
-    }
-    
-    public static function decode($input) {
-        if(empty($input)) return;
-        $input = strtoupper($input);
-        $paddingCharCount = substr_count($input, self::$map[32]);
-        $allowedValues = array(6,4,3,1,0);
-        if(!in_array($paddingCharCount, $allowedValues)) return false;
-        for($i=0; $i<4; $i++){ 
-            if($paddingCharCount == $allowedValues[$i] && 
-                substr($input, -($allowedValues[$i])) != str_repeat(self::$map[32], $allowedValues[$i])) return false;
-        }
-        $input = str_replace('=','', $input);
-        $input = str_split($input);
-        $binaryString = "";
-        for($i=0; $i < count($input); $i = $i+8) {
-            $x = "";
-            if(!in_array($input[$i], self::$map)) return false;
-            for($j=0; $j < 8; $j++) {
-                $x .= str_pad(base_convert(@self::$flippedMap[@$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
-            }
-            $eightBits = str_split($x, 8);
-            for($z = 0; $z < count($eightBits); $z++) {
-                $binaryString .= ( ($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48 ) ? $y:"";
-            }
-        }
-        return $binaryString;
-    }
-}
-
diff --git a/leed/otphp/vendor/libs.php b/leed/otphp/vendor/libs.php
deleted file mode 100644
index 742c7b98eba6e635714eef61649f34068ee9bd2a..0000000000000000000000000000000000000000
--- a/leed/otphp/vendor/libs.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-// Add any needed third party library to this directory
-
-//require_once dirname(__FILE__).'/some_lib/lib.php';
-require_once dirname(__FILE__).'/base32.php';
diff --git a/leed/phpqrcode.php b/leed/phpqrcode.php
deleted file mode 100644
index 80adb9df239cb4cbd05cc51295f5eef5e5bbf8e7..0000000000000000000000000000000000000000
--- a/leed/phpqrcode.php
+++ /dev/null
@@ -1,3312 +0,0 @@
-<?php
-
-/*
- * PHP QR Code encoder
- *
- * This file contains MERGED version of PHP QR Code library.
- * It was auto-generated from full version for your convenience.
- *
- * This merged version was configured to not requre any external files,
- * with disabled cache, error loging and weker but faster mask matching.
- * If you need tune it up please use non-merged version.
- *
- * For full version, documentation, examples of use please visit:
- *
- *    http://phpqrcode.sourceforge.net/
- *    https://sourceforge.net/projects/phpqrcode/
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
- 
-
-/*
- * Version: 1.1.4
- * Build: 2010100721
- */
-
-
-
-//---- qrconst.php -----------------------------
-
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Common constants
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-	// Encoding modes
-	 
-	define('QR_MODE_NUL', -1);
-	define('QR_MODE_NUM', 0);
-	define('QR_MODE_AN', 1);
-	define('QR_MODE_8', 2);
-	define('QR_MODE_KANJI', 3);
-	define('QR_MODE_STRUCTURE', 4);
-
-	// Levels of error correction.
-
-	define('QR_ECLEVEL_L', 0);
-	define('QR_ECLEVEL_M', 1);
-	define('QR_ECLEVEL_Q', 2);
-	define('QR_ECLEVEL_H', 3);
-	
-	// Supported output formats
-	
-	define('QR_FORMAT_TEXT', 0);
-	define('QR_FORMAT_PNG',  1);
-	
-	class qrstr {
-		public static function set(&$srctab, $x, $y, $repl, $replLen = false) {
-			$srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl));
-		}
-	}	
-
-
-
-//---- merged_config.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Config file, tuned-up for merged verion
- */
-     
-    define('QR_CACHEABLE', false);       // use cache - more disk reads but less CPU power, masks and format templates are stored there
-    define('QR_CACHE_DIR', false);       // used when QR_CACHEABLE === true
-    define('QR_LOG_DIR', false);         // default error logs dir   
-    
-    define('QR_FIND_BEST_MASK', true);                                                          // if true, estimates best mask (spec. default, but extremally slow; set to false to significant performance boost but (propably) worst quality code
-    define('QR_FIND_FROM_RANDOM', 2);                                                       // if false, checks all masks available, otherwise value tells count of masks need to be checked, mask id are got randomly
-    define('QR_DEFAULT_MASK', 2);                                                               // when QR_FIND_BEST_MASK === false
-                                                  
-    define('QR_PNG_MAXIMUM_SIZE',  1024);                                                       // maximum allowed png image width (in pixels), tune to make sure GD and PHP can handle such big images
-                                                  
-
-
-
-//---- qrtools.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Toolset, handy and debug utilites.
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-    class QRtools {
-    
-        //----------------------------------------------------------------------
-        public static function binarize($frame)
-        {
-            $len = count($frame);
-            foreach ($frame as &$frameLine) {
-                
-                for($i=0; $i<$len; $i++) {
-                    $frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0';
-                }
-            }
-            
-            return $frame;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function tcpdfBarcodeArray($code, $mode = 'QR,L', $tcPdfVersion = '4.5.037')
-        {
-            $barcode_array = array();
-            
-            if (!is_array($mode))
-                $mode = explode(',', $mode);
-                
-            $eccLevel = 'L';
-                
-            if (count($mode) > 1) {
-                $eccLevel = $mode[1];
-            }
-                
-            $qrTab = QRcode::text($code, false, $eccLevel);
-            $size = count($qrTab);
-                
-            $barcode_array['num_rows'] = $size;
-            $barcode_array['num_cols'] = $size;
-            $barcode_array['bcode'] = array();
-                
-            foreach ($qrTab as $line) {
-                $arrAdd = array();
-                foreach(str_split($line) as $char)
-                    $arrAdd[] = ($char=='1')?1:0;
-                $barcode_array['bcode'][] = $arrAdd;
-            }
-                    
-            return $barcode_array;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function clearCache()
-        {
-            self::$frames = array();
-        }
-        
-        //----------------------------------------------------------------------
-        public static function buildCache()
-        {
-			QRtools::markTime('before_build_cache');
-			
-			$mask = new QRmask();
-            for ($a=1; $a <= QRSPEC_VERSION_MAX; $a++) {
-                $frame = QRspec::newFrame($a);
-                if (QR_IMAGE) {
-                    $fileName = QR_CACHE_DIR.'frame_'.$a.'.png';
-                    QRimage::png(self::binarize($frame), $fileName, 1, 0);
-                }
-				
-				$width = count($frame);
-				$bitMask = array_fill(0, $width, array_fill(0, $width, 0));
-				for ($maskNo=0; $maskNo<8; $maskNo++)
-					$mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true);
-            }
-			
-			QRtools::markTime('after_build_cache');
-        }
-
-        //----------------------------------------------------------------------
-        public static function log($outfile, $err)
-        {
-            if (QR_LOG_DIR !== false) {
-                if ($err != '') {
-                    if ($outfile !== false) {
-                        file_put_contents(QR_LOG_DIR.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
-                    } else {
-                        file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
-                    }
-                }    
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public static function dumpMask($frame) 
-        {
-            $width = count($frame);
-            for($y=0;$y<$width;$y++) {
-                for($x=0;$x<$width;$x++) {
-                    echo ord($frame[$y][$x]).',';
-                }
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public static function markTime($markerId)
-        {
-            list($usec, $sec) = explode(" ", microtime());
-            $time = ((float)$usec + (float)$sec);
-            
-            if (!isset($GLOBALS['qr_time_bench']))
-                $GLOBALS['qr_time_bench'] = array();
-            
-            $GLOBALS['qr_time_bench'][$markerId] = $time;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function timeBenchmark()
-        {
-            self::markTime('finish');
-        
-            $lastTime = 0;
-            $startTime = 0;
-            $p = 0;
-
-            echo '<table cellpadding="3" cellspacing="1">
-                    <thead><tr style="border-bottom:1px solid silver"><td colspan="2" style="text-align:center">BENCHMARK</td></tr></thead>
-                    <tbody>';
-
-            foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) {
-                if ($p > 0) {
-                    echo '<tr><th style="text-align:right">till '.$markerId.': </th><td>'.number_format($thisTime-$lastTime, 6).'s</td></tr>';
-                } else {
-                    $startTime = $thisTime;
-                }
-                
-                $p++;
-                $lastTime = $thisTime;
-            }
-            
-            echo '</tbody><tfoot>
-                <tr style="border-top:2px solid black"><th style="text-align:right">TOTAL: </th><td>'.number_format($lastTime-$startTime, 6).'s</td></tr>
-            </tfoot>
-            </table>';
-        }
-        
-    }
-    
-    //##########################################################################
-    
-    QRtools::markTime('start');
-    
-
-
-
-//---- qrspec.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * QR Code specifications
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * The following data / specifications are taken from
- * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
- *  or
- * "Automatic identification and data capture techniques -- 
- *  QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-    define('QRSPEC_VERSION_MAX', 40);
-    define('QRSPEC_WIDTH_MAX',   177);
-
-    define('QRCAP_WIDTH',        0);
-    define('QRCAP_WORDS',        1);
-    define('QRCAP_REMINDER',     2);
-    define('QRCAP_EC',           3);
-
-    class QRspec {
-    
-        public static $capacity = array(
-            array(  0,    0, 0, array(   0,    0,    0,    0)),
-            array( 21,   26, 0, array(   7,   10,   13,   17)), // 1
-            array( 25,   44, 7, array(  10,   16,   22,   28)),
-            array( 29,   70, 7, array(  15,   26,   36,   44)),
-            array( 33,  100, 7, array(  20,   36,   52,   64)),
-            array( 37,  134, 7, array(  26,   48,   72,   88)), // 5
-            array( 41,  172, 7, array(  36,   64,   96,  112)),
-            array( 45,  196, 0, array(  40,   72,  108,  130)),
-            array( 49,  242, 0, array(  48,   88,  132,  156)),
-            array( 53,  292, 0, array(  60,  110,  160,  192)),
-            array( 57,  346, 0, array(  72,  130,  192,  224)), //10
-            array( 61,  404, 0, array(  80,  150,  224,  264)),
-            array( 65,  466, 0, array(  96,  176,  260,  308)),
-            array( 69,  532, 0, array( 104,  198,  288,  352)),
-            array( 73,  581, 3, array( 120,  216,  320,  384)),
-            array( 77,  655, 3, array( 132,  240,  360,  432)), //15
-            array( 81,  733, 3, array( 144,  280,  408,  480)),
-            array( 85,  815, 3, array( 168,  308,  448,  532)),
-            array( 89,  901, 3, array( 180,  338,  504,  588)),
-            array( 93,  991, 3, array( 196,  364,  546,  650)),
-            array( 97, 1085, 3, array( 224,  416,  600,  700)), //20
-            array(101, 1156, 4, array( 224,  442,  644,  750)),
-            array(105, 1258, 4, array( 252,  476,  690,  816)),
-            array(109, 1364, 4, array( 270,  504,  750,  900)),
-            array(113, 1474, 4, array( 300,  560,  810,  960)),
-            array(117, 1588, 4, array( 312,  588,  870, 1050)), //25
-            array(121, 1706, 4, array( 336,  644,  952, 1110)),
-            array(125, 1828, 4, array( 360,  700, 1020, 1200)),
-            array(129, 1921, 3, array( 390,  728, 1050, 1260)),
-            array(133, 2051, 3, array( 420,  784, 1140, 1350)),
-            array(137, 2185, 3, array( 450,  812, 1200, 1440)), //30
-            array(141, 2323, 3, array( 480,  868, 1290, 1530)),
-            array(145, 2465, 3, array( 510,  924, 1350, 1620)),
-            array(149, 2611, 3, array( 540,  980, 1440, 1710)),
-            array(153, 2761, 3, array( 570, 1036, 1530, 1800)),
-            array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35
-            array(161, 3034, 0, array( 600, 1120, 1680, 1980)),
-            array(165, 3196, 0, array( 630, 1204, 1770, 2100)),
-            array(169, 3362, 0, array( 660, 1260, 1860, 2220)),
-            array(173, 3532, 0, array( 720, 1316, 1950, 2310)),
-            array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40
-        );
-        
-        //----------------------------------------------------------------------
-        public static function getDataLength($version, $level)
-        {
-            return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level];
-        }
-        
-        //----------------------------------------------------------------------
-        public static function getECCLength($version, $level)
-        {
-            return self::$capacity[$version][QRCAP_EC][$level];
-        }
-        
-        //----------------------------------------------------------------------
-        public static function getWidth($version)
-        {
-            return self::$capacity[$version][QRCAP_WIDTH];
-        }
-        
-        //----------------------------------------------------------------------
-        public static function getRemainder($version)
-        {
-            return self::$capacity[$version][QRCAP_REMINDER];
-        }
-        
-        //----------------------------------------------------------------------
-        public static function getMinimumVersion($size, $level)
-        {
-
-            for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) {
-                $words  = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level];
-                if($words >= $size) 
-                    return $i;
-            }
-
-            return -1;
-        }
-    
-        //######################################################################
-        
-        public static $lengthTableBits = array(
-            array(10, 12, 14),
-            array( 9, 11, 13),
-            array( 8, 16, 16),
-            array( 8, 10, 12)
-        );
-        
-        //----------------------------------------------------------------------
-        public static function lengthIndicator($mode, $version)
-        {
-            if ($mode == QR_MODE_STRUCTURE)
-                return 0;
-                
-            if ($version <= 9) {
-                $l = 0;
-            } else if ($version <= 26) {
-                $l = 1;
-            } else {
-                $l = 2;
-            }
-
-            return self::$lengthTableBits[$mode][$l];
-        }
-        
-        //----------------------------------------------------------------------
-        public static function maximumWords($mode, $version)
-        {
-            if($mode == QR_MODE_STRUCTURE) 
-                return 3;
-                
-            if($version <= 9) {
-                $l = 0;
-            } else if($version <= 26) {
-                $l = 1;
-            } else {
-                $l = 2;
-            }
-
-            $bits = self::$lengthTableBits[$mode][$l];
-            $words = (1 << $bits) - 1;
-            
-            if($mode == QR_MODE_KANJI) {
-                $words *= 2; // the number of bytes is required
-            }
-
-            return $words;
-        }
-
-        // Error correction code -----------------------------------------------
-        // Table of the error correction code (Reed-Solomon block)
-        // See Table 12-16 (pp.30-36), JIS X0510:2004.
-
-        public static $eccTable = array(
-            array(array( 0,  0), array( 0,  0), array( 0,  0), array( 0,  0)),
-            array(array( 1,  0), array( 1,  0), array( 1,  0), array( 1,  0)), // 1
-            array(array( 1,  0), array( 1,  0), array( 1,  0), array( 1,  0)),
-            array(array( 1,  0), array( 1,  0), array( 2,  0), array( 2,  0)),
-            array(array( 1,  0), array( 2,  0), array( 2,  0), array( 4,  0)),
-            array(array( 1,  0), array( 2,  0), array( 2,  2), array( 2,  2)), // 5
-            array(array( 2,  0), array( 4,  0), array( 4,  0), array( 4,  0)),
-            array(array( 2,  0), array( 4,  0), array( 2,  4), array( 4,  1)),
-            array(array( 2,  0), array( 2,  2), array( 4,  2), array( 4,  2)),
-            array(array( 2,  0), array( 3,  2), array( 4,  4), array( 4,  4)),
-            array(array( 2,  2), array( 4,  1), array( 6,  2), array( 6,  2)), //10
-            array(array( 4,  0), array( 1,  4), array( 4,  4), array( 3,  8)),
-            array(array( 2,  2), array( 6,  2), array( 4,  6), array( 7,  4)),
-            array(array( 4,  0), array( 8,  1), array( 8,  4), array(12,  4)),
-            array(array( 3,  1), array( 4,  5), array(11,  5), array(11,  5)),
-            array(array( 5,  1), array( 5,  5), array( 5,  7), array(11,  7)), //15
-            array(array( 5,  1), array( 7,  3), array(15,  2), array( 3, 13)),
-            array(array( 1,  5), array(10,  1), array( 1, 15), array( 2, 17)),
-            array(array( 5,  1), array( 9,  4), array(17,  1), array( 2, 19)),
-            array(array( 3,  4), array( 3, 11), array(17,  4), array( 9, 16)),
-            array(array( 3,  5), array( 3, 13), array(15,  5), array(15, 10)), //20
-            array(array( 4,  4), array(17,  0), array(17,  6), array(19,  6)),
-            array(array( 2,  7), array(17,  0), array( 7, 16), array(34,  0)),
-            array(array( 4,  5), array( 4, 14), array(11, 14), array(16, 14)),
-            array(array( 6,  4), array( 6, 14), array(11, 16), array(30,  2)),
-            array(array( 8,  4), array( 8, 13), array( 7, 22), array(22, 13)), //25
-            array(array(10,  2), array(19,  4), array(28,  6), array(33,  4)),
-            array(array( 8,  4), array(22,  3), array( 8, 26), array(12, 28)),
-            array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)),
-            array(array( 7,  7), array(21,  7), array( 1, 37), array(19, 26)),
-            array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30
-            array(array(13,  3), array( 2, 29), array(42,  1), array(23, 28)),
-            array(array(17,  0), array(10, 23), array(10, 35), array(19, 35)),
-            array(array(17,  1), array(14, 21), array(29, 19), array(11, 46)),
-            array(array(13,  6), array(14, 23), array(44,  7), array(59,  1)),
-            array(array(12,  7), array(12, 26), array(39, 14), array(22, 41)), //35
-            array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)),
-            array(array(17,  4), array(29, 14), array(49, 10), array(24, 46)),
-            array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)),
-            array(array(20,  4), array(40,  7), array(43, 22), array(10, 67)),
-            array(array(19,  6), array(18, 31), array(34, 34), array(20, 61)),//40
-        );                                                                       
-
-        //----------------------------------------------------------------------
-        // CACHEABLE!!!
-        
-        public static function getEccSpec($version, $level, array &$spec)
-        {
-            if (count($spec) < 5) {
-                $spec = array(0,0,0,0,0);
-            }
-
-            $b1   = self::$eccTable[$version][$level][0];
-            $b2   = self::$eccTable[$version][$level][1];
-            $data = self::getDataLength($version, $level);
-            $ecc  = self::getECCLength($version, $level);
-
-            if($b2 == 0) {
-                $spec[0] = $b1;
-                $spec[1] = (int)($data / $b1);
-                $spec[2] = (int)($ecc / $b1);
-                $spec[3] = 0; 
-                $spec[4] = 0;
-            } else {
-                $spec[0] = $b1;
-                $spec[1] = (int)($data / ($b1 + $b2));
-                $spec[2] = (int)($ecc  / ($b1 + $b2));
-                $spec[3] = $b2;
-                $spec[4] = $spec[1] + 1;
-            }
-        }
-
-        // Alignment pattern ---------------------------------------------------
-
-        // Positions of alignment patterns.
-        // This array includes only the second and the third position of the 
-        // alignment patterns. Rest of them can be calculated from the distance 
-        // between them.
-         
-        // See Table 1 in Appendix E (pp.71) of JIS X0510:2004.
-         
-        public static $alignmentPattern = array(      
-            array( 0,  0),
-            array( 0,  0), array(18,  0), array(22,  0), array(26,  0), array(30,  0), // 1- 5
-            array(34,  0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10
-            array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15
-            array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20
-            array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25
-            array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30
-            array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35
-            array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40
-        );                                                                                  
-
-        
-        /** --------------------------------------------------------------------
-         * Put an alignment marker.
-         * @param frame
-         * @param width
-         * @param ox,oy center coordinate of the pattern
-         */
-        public static function putAlignmentMarker(array &$frame, $ox, $oy)
-        {
-            $finder = array(
-                "\xa1\xa1\xa1\xa1\xa1",
-                "\xa1\xa0\xa0\xa0\xa1",
-                "\xa1\xa0\xa1\xa0\xa1",
-                "\xa1\xa0\xa0\xa0\xa1",
-                "\xa1\xa1\xa1\xa1\xa1"
-            );                        
-            
-            $yStart = $oy-2;         
-            $xStart = $ox-2;
-            
-            for($y=0; $y<5; $y++) {
-                QRstr::set($frame, $xStart, $yStart+$y, $finder[$y]);
-            }
-        }
-
-        //----------------------------------------------------------------------
-        public static function putAlignmentPattern($version, &$frame, $width)
-        {
-            if($version < 2)
-                return;
-
-            $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0];
-            if($d < 0) {
-                $w = 2;
-            } else {
-                $w = (int)(($width - self::$alignmentPattern[$version][0]) / $d + 2);
-            }
-
-            if($w * $w - 3 == 1) {
-                $x = self::$alignmentPattern[$version][0];
-                $y = self::$alignmentPattern[$version][0];
-                self::putAlignmentMarker($frame, $x, $y);
-                return;
-            }
-
-            $cx = self::$alignmentPattern[$version][0];
-            for($x=1; $x<$w - 1; $x++) {
-                self::putAlignmentMarker($frame, 6, $cx);
-                self::putAlignmentMarker($frame, $cx,  6);
-                $cx += $d;
-            }
-
-            $cy = self::$alignmentPattern[$version][0];
-            for($y=0; $y<$w-1; $y++) {
-                $cx = self::$alignmentPattern[$version][0];
-                for($x=0; $x<$w-1; $x++) {
-                    self::putAlignmentMarker($frame, $cx, $cy);
-                    $cx += $d;
-                }
-                $cy += $d;
-            }
-        }
-
-        // Version information pattern -----------------------------------------
-
-		// Version information pattern (BCH coded).
-        // See Table 1 in Appendix D (pp.68) of JIS X0510:2004.
-        
-		// size: [QRSPEC_VERSION_MAX - 6]
-		
-        public static $versionPattern = array(
-            0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
-            0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
-            0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
-            0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
-            0x27541, 0x28c69
-        );
-
-        //----------------------------------------------------------------------
-        public static function getVersionPattern($version)
-        {
-            if($version < 7 || $version > QRSPEC_VERSION_MAX)
-                return 0;
-
-            return self::$versionPattern[$version -7];
-        }
-
-        // Format information --------------------------------------------------
-        // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib)
-        
-        public static $formatInfo = array(
-            array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976),
-            array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0),
-            array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed),
-            array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b)
-        );
-
-        public static function getFormatInfo($mask, $level)
-        {
-            if($mask < 0 || $mask > 7)
-                return 0;
-                
-            if($level < 0 || $level > 3)
-                return 0;                
-
-            return self::$formatInfo[$level][$mask];
-        }
-
-        // Frame ---------------------------------------------------------------
-        // Cache of initial frames.
-         
-        public static $frames = array();
-
-        /** --------------------------------------------------------------------
-         * Put a finder pattern.
-         * @param frame
-         * @param width
-         * @param ox,oy upper-left coordinate of the pattern
-         */
-        public static function putFinderPattern(&$frame, $ox, $oy)
-        {
-            $finder = array(
-                "\xc1\xc1\xc1\xc1\xc1\xc1\xc1",
-                "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
-                "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
-                "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
-                "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
-                "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
-                "\xc1\xc1\xc1\xc1\xc1\xc1\xc1"
-            );                            
-            
-            for($y=0; $y<7; $y++) {
-                QRstr::set($frame, $ox, $oy+$y, $finder[$y]);
-            }
-        }
-
-        //----------------------------------------------------------------------
-        public static function createFrame($version)
-        {
-            $width = self::$capacity[$version][QRCAP_WIDTH];
-            $frameLine = str_repeat ("\0", $width);
-            $frame = array_fill(0, $width, $frameLine);
-
-            // Finder pattern
-            self::putFinderPattern($frame, 0, 0);
-            self::putFinderPattern($frame, $width - 7, 0);
-            self::putFinderPattern($frame, 0, $width - 7);
-            
-            // Separator
-            $yOffset = $width - 7;
-            
-            for($y=0; $y<7; $y++) {
-                $frame[$y][7] = "\xc0";
-                $frame[$y][$width - 8] = "\xc0";
-                $frame[$yOffset][7] = "\xc0";
-                $yOffset++;
-            }
-            
-            $setPattern = str_repeat("\xc0", 8);
-            
-            QRstr::set($frame, 0, 7, $setPattern);
-            QRstr::set($frame, $width-8, 7, $setPattern);
-            QRstr::set($frame, 0, $width - 8, $setPattern);
-        
-            // Format info
-            $setPattern = str_repeat("\x84", 9);
-            QRstr::set($frame, 0, 8, $setPattern);
-            QRstr::set($frame, $width - 8, 8, $setPattern, 8);
-            
-            $yOffset = $width - 8;
-
-            for($y=0; $y<8; $y++,$yOffset++) {
-                $frame[$y][8] = "\x84";
-                $frame[$yOffset][8] = "\x84";
-            }
-
-            // Timing pattern  
-            
-            for($i=1; $i<$width-15; $i++) {
-                $frame[6][7+$i] = chr(0x90 | ($i & 1));
-                $frame[7+$i][6] = chr(0x90 | ($i & 1));
-            }
-            
-            // Alignment pattern  
-            self::putAlignmentPattern($version, $frame, $width);
-            
-            // Version information 
-            if($version >= 7) {
-                $vinf = self::getVersionPattern($version);
-
-                $v = $vinf;
-                
-                for($x=0; $x<6; $x++) {
-                    for($y=0; $y<3; $y++) {
-                        $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1));
-                        $v = $v >> 1;
-                    }
-                }
-
-                $v = $vinf;
-                for($y=0; $y<6; $y++) {
-                    for($x=0; $x<3; $x++) {
-                        $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1));
-                        $v = $v >> 1;
-                    }
-                }
-            }
-    
-            // and a little bit...  
-            $frame[$width - 8][8] = "\x81";
-            
-            return $frame;
-        }
-
-        //----------------------------------------------------------------------
-        public static function debug($frame, $binary_mode = false)
-        {
-            if ($binary_mode) {
-            
-                    foreach ($frame as &$frameLine) {
-                        $frameLine = join('<span class="m">&nbsp;&nbsp;</span>', explode('0', $frameLine));
-                        $frameLine = join('&#9608;&#9608;', explode('1', $frameLine));
-                    }
-                    
-                    ?>
-                <style>
-                    .m { background-color: white; }
-                </style>
-                <?php
-                    echo '<pre><tt><br/ ><br/ ><br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
-                    echo join("<br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", $frame);
-                    echo '</tt></pre><br/ ><br/ ><br/ ><br/ ><br/ ><br/ >';
-            
-            } else {
-            
-                foreach ($frame as &$frameLine) {
-                    $frameLine = join('<span class="m">&nbsp;</span>',  explode("\xc0", $frameLine));
-                    $frameLine = join('<span class="m">&#9618;</span>', explode("\xc1", $frameLine));
-                    $frameLine = join('<span class="p">&nbsp;</span>',  explode("\xa0", $frameLine));
-                    $frameLine = join('<span class="p">&#9618;</span>', explode("\xa1", $frameLine));
-                    $frameLine = join('<span class="s">&#9671;</span>', explode("\x84", $frameLine)); //format 0
-                    $frameLine = join('<span class="s">&#9670;</span>', explode("\x85", $frameLine)); //format 1
-                    $frameLine = join('<span class="x">&#9762;</span>', explode("\x81", $frameLine)); //special bit
-                    $frameLine = join('<span class="c">&nbsp;</span>',  explode("\x90", $frameLine)); //clock 0
-                    $frameLine = join('<span class="c">&#9719;</span>', explode("\x91", $frameLine)); //clock 1
-                    $frameLine = join('<span class="f">&nbsp;</span>',  explode("\x88", $frameLine)); //version
-                    $frameLine = join('<span class="f">&#9618;</span>', explode("\x89", $frameLine)); //version
-                    $frameLine = join('&#9830;', explode("\x01", $frameLine));
-                    $frameLine = join('&#8901;', explode("\0", $frameLine));
-                }
-                
-                ?>
-                <style>
-                    .p { background-color: yellow; }
-                    .m { background-color: #00FF00; }
-                    .s { background-color: #FF0000; }
-                    .c { background-color: aqua; }
-                    .x { background-color: pink; }
-                    .f { background-color: gold; }
-                </style>
-                <?php
-                echo "<pre><tt>";
-                echo join("<br/ >", $frame);
-                echo "</tt></pre>";
-            
-            }
-        }
-
-        //----------------------------------------------------------------------
-        public static function serial($frame)
-        {
-            return gzcompress(join("\n", $frame), 9);
-        }
-        
-        //----------------------------------------------------------------------
-        public static function unserial($code)
-        {
-            return explode("\n", gzuncompress($code));
-        }
-        
-        //----------------------------------------------------------------------
-        public static function newFrame($version)
-        {
-            if($version < 1 || $version > QRSPEC_VERSION_MAX) 
-                return null;
-
-            if(!isset(self::$frames[$version])) {
-                
-                $fileName = QR_CACHE_DIR.'frame_'.$version.'.dat';
-                
-                if (QR_CACHEABLE) {
-                    if (file_exists($fileName)) {
-                        self::$frames[$version] = self::unserial(file_get_contents($fileName));
-                    } else {
-                        self::$frames[$version] = self::createFrame($version);
-                        file_put_contents($fileName, self::serial(self::$frames[$version]));
-                    }
-                } else {
-                    self::$frames[$version] = self::createFrame($version);
-                }
-            }
-            
-            if(is_null(self::$frames[$version]))
-                return null;
-
-            return self::$frames[$version];
-        }
-
-        //----------------------------------------------------------------------
-        public static function rsBlockNum($spec)     { return $spec[0] + $spec[3]; }
-        public static function rsBlockNum1($spec)    { return $spec[0]; }
-        public static function rsDataCodes1($spec)   { return $spec[1]; }
-        public static function rsEccCodes1($spec)    { return $spec[2]; }
-        public static function rsBlockNum2($spec)    { return $spec[3]; }
-        public static function rsDataCodes2($spec)   { return $spec[4]; }
-        public static function rsEccCodes2($spec)    { return $spec[2]; }
-        public static function rsDataLength($spec)   { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]);    }
-        public static function rsEccLength($spec)    { return ($spec[0] + $spec[3]) * $spec[2]; }
-        
-    }
-
-
-
-//---- qrimage.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Image output of code using GD2
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-    define('QR_IMAGE', true);
-
-    class QRimage {
-    
-        //----------------------------------------------------------------------
-        public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE) 
-        {
-            $image = self::image($frame, $pixelPerPoint, $outerFrame);
-            
-            if ($filename === false) {
-                Header("Content-type: image/png");
-                ImagePng($image);
-            } else {
-                if($saveandprint===TRUE){
-                    ImagePng($image, $filename);
-                    header("Content-type: image/png");
-                    ImagePng($image);
-                }else{
-                    ImagePng($image, $filename);
-                }
-            }
-            
-            ImageDestroy($image);
-        }
-    
-        //----------------------------------------------------------------------
-        public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85) 
-        {
-            $image = self::image($frame, $pixelPerPoint, $outerFrame);
-            
-            if ($filename === false) {
-                Header("Content-type: image/jpeg");
-                ImageJpeg($image, null, $q);
-            } else {
-                ImageJpeg($image, $filename, $q);            
-            }
-            
-            ImageDestroy($image);
-        }
-    
-        //----------------------------------------------------------------------
-        private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4) 
-        {
-            $h = count($frame);
-            $w = strlen($frame[0]);
-            
-            $imgW = $w + 2*$outerFrame;
-            $imgH = $h + 2*$outerFrame;
-            
-            $base_image =ImageCreate($imgW, $imgH);
-            
-            $col[0] = ImageColorAllocate($base_image,255,255,255);
-            $col[1] = ImageColorAllocate($base_image,0,0,0);
-
-            imagefill($base_image, 0, 0, $col[0]);
-
-            for($y=0; $y<$h; $y++) {
-                for($x=0; $x<$w; $x++) {
-                    if ($frame[$y][$x] == '1') {
-                        ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]); 
-                    }
-                }
-            }
-            
-            $target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint);
-            ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
-            ImageDestroy($base_image);
-            
-            return $target_image;
-        }
-    }
-
-
-
-//---- qrinput.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Input encoding class
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-    define('STRUCTURE_HEADER_BITS',  20);
-    define('MAX_STRUCTURED_SYMBOLS', 16);
-
-    class QRinputItem {
-    
-        public $mode;
-        public $size;
-        public $data;
-        public $bstream;
-
-        public function __construct($mode, $size, $data, $bstream = null) 
-        {
-            $setData = array_slice($data, 0, $size);
-            
-            if (count($setData) < $size) {
-                $setData = array_merge($setData, array_fill(0,$size-count($setData),0));
-            }
-        
-            if(!QRinput::check($mode, $size, $setData)) {
-                throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData));
-                return null;
-            }
-            
-            $this->mode = $mode;
-            $this->size = $size;
-            $this->data = $setData;
-            $this->bstream = $bstream;
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeModeNum($version)
-        {
-            try {
-            
-                $words = (int)($this->size / 3);
-                $bs = new QRbitstream();
-                
-                $val = 0x1;
-                $bs->appendNum(4, $val);
-                $bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size);
-
-                for($i=0; $i<$words; $i++) {
-                    $val  = (ord($this->data[$i*3  ]) - ord('0')) * 100;
-                    $val += (ord($this->data[$i*3+1]) - ord('0')) * 10;
-                    $val += (ord($this->data[$i*3+2]) - ord('0'));
-                    $bs->appendNum(10, $val);
-                }
-
-                if($this->size - $words * 3 == 1) {
-                    $val = ord($this->data[$words*3]) - ord('0');
-                    $bs->appendNum(4, $val);
-                } else if($this->size - $words * 3 == 2) {
-                    $val  = (ord($this->data[$words*3  ]) - ord('0')) * 10;
-                    $val += (ord($this->data[$words*3+1]) - ord('0'));
-                    $bs->appendNum(7, $val);
-                }
-
-                $this->bstream = $bs;
-                return 0;
-                
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeModeAn($version)
-        {
-            try {
-                $words = (int)($this->size / 2);
-                $bs = new QRbitstream();
-                
-                $bs->appendNum(4, 0x02);
-                $bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size);
-
-                for($i=0; $i<$words; $i++) {
-                    $val  = (int)QRinput::lookAnTable(ord($this->data[$i*2  ])) * 45;
-                    $val += (int)QRinput::lookAnTable(ord($this->data[$i*2+1]));
-
-                    $bs->appendNum(11, $val);
-                }
-
-                if($this->size & 1) {
-                    $val = QRinput::lookAnTable(ord($this->data[$words * 2]));
-                    $bs->appendNum(6, $val);
-                }
-        
-                $this->bstream = $bs;
-                return 0;
-            
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeMode8($version)
-        {
-            try {
-                $bs = new QRbitstream();
-
-                $bs->appendNum(4, 0x4);
-                $bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size);
-
-                for($i=0; $i<$this->size; $i++) {
-                    $bs->appendNum(8, ord($this->data[$i]));
-                }
-
-                $this->bstream = $bs;
-                return 0;
-            
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeModeKanji($version)
-        {
-            try {
-
-                $bs = new QRbitrtream();
-                
-                $bs->appendNum(4, 0x8);
-                $bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2));
-
-                for($i=0; $i<$this->size; $i+=2) {
-                    $val = (ord($this->data[$i]) << 8) | ord($this->data[$i+1]);
-                    if($val <= 0x9ffc) {
-                        $val -= 0x8140;
-                    } else {
-                        $val -= 0xc140;
-                    }
-                    
-                    $h = ($val >> 8) * 0xc0;
-                    $val = ($val & 0xff) + $h;
-
-                    $bs->appendNum(13, $val);
-                }
-
-                $this->bstream = $bs;
-                return 0;
-            
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-
-        //----------------------------------------------------------------------
-        public function encodeModeStructure()
-        {
-            try {
-                $bs =  new QRbitstream();
-                
-                $bs->appendNum(4, 0x03);
-                $bs->appendNum(4, ord($this->data[1]) - 1);
-                $bs->appendNum(4, ord($this->data[0]) - 1);
-                $bs->appendNum(8, ord($this->data[2]));
-
-                $this->bstream = $bs;
-                return 0;
-            
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public function estimateBitStreamSizeOfEntry($version)
-        {
-            $bits = 0;
-
-            if($version == 0) 
-                $version = 1;
-
-            switch($this->mode) {
-                case QR_MODE_NUM:        $bits = QRinput::estimateBitsModeNum($this->size);    break;
-                case QR_MODE_AN:        $bits = QRinput::estimateBitsModeAn($this->size);    break;
-                case QR_MODE_8:            $bits = QRinput::estimateBitsMode8($this->size);    break;
-                case QR_MODE_KANJI:        $bits = QRinput::estimateBitsModeKanji($this->size);break;
-                case QR_MODE_STRUCTURE:    return STRUCTURE_HEADER_BITS;            
-                default:
-                    return 0;
-            }
-
-            $l = QRspec::lengthIndicator($this->mode, $version);
-            $m = 1 << $l;
-            $num = (int)(($this->size + $m - 1) / $m);
-
-            $bits += $num * (4 + $l);
-
-            return $bits;
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeBitStream($version)
-        {
-            try {
-            
-                unset($this->bstream);
-                $words = QRspec::maximumWords($this->mode, $version);
-                
-                if($this->size > $words) {
-                
-                    $st1 = new QRinputItem($this->mode, $words, $this->data);
-                    $st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words));
-
-                    $st1->encodeBitStream($version);
-                    $st2->encodeBitStream($version);
-                    
-                    $this->bstream = new QRbitstream();
-                    $this->bstream->append($st1->bstream);
-                    $this->bstream->append($st2->bstream);
-                    
-                    unset($st1);
-                    unset($st2);
-                    
-                } else {
-                    
-                    $ret = 0;
-                    
-                    switch($this->mode) {
-                        case QR_MODE_NUM:        $ret = $this->encodeModeNum($version);    break;
-                        case QR_MODE_AN:        $ret = $this->encodeModeAn($version);    break;
-                        case QR_MODE_8:            $ret = $this->encodeMode8($version);    break;
-                        case QR_MODE_KANJI:        $ret = $this->encodeModeKanji($version);break;
-                        case QR_MODE_STRUCTURE:    $ret = $this->encodeModeStructure();    break;
-                        
-                        default:
-                            break;
-                    }
-                    
-                    if($ret < 0)
-                        return -1;
-                }
-
-                return $this->bstream->size();
-            
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-    };
-    
-    //##########################################################################
-
-    class QRinput {
-
-        public $items;
-        
-        private $version;
-        private $level;
-        
-        //----------------------------------------------------------------------
-        public function __construct($version = 0, $level = QR_ECLEVEL_L)
-        {
-            if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) {
-                throw new Exception('Invalid version no');
-                return NULL;
-            }
-            
-            $this->version = $version;
-            $this->level = $level;
-        }
-        
-        //----------------------------------------------------------------------
-        public function getVersion()
-        {
-            return $this->version;
-        }
-        
-        //----------------------------------------------------------------------
-        public function setVersion($version)
-        {
-            if($version < 0 || $version > QRSPEC_VERSION_MAX) {
-                throw new Exception('Invalid version no');
-                return -1;
-            }
-
-            $this->version = $version;
-
-            return 0;
-        }
-        
-        //----------------------------------------------------------------------
-        public function getErrorCorrectionLevel()
-        {
-            return $this->level;
-        }
-
-        //----------------------------------------------------------------------
-        public function setErrorCorrectionLevel($level)
-        {
-            if($level > QR_ECLEVEL_H) {
-                throw new Exception('Invalid ECLEVEL');
-                return -1;
-            }
-
-            $this->level = $level;
-
-            return 0;
-        }
-        
-        //----------------------------------------------------------------------
-        public function appendEntry(QRinputItem $entry)
-        {
-            $this->items[] = $entry;
-        }
-        
-        //----------------------------------------------------------------------
-        public function append($mode, $size, $data)
-        {
-            try {
-                $entry = new QRinputItem($mode, $size, $data);
-                $this->items[] = $entry;
-                return 0;
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        
-        public function insertStructuredAppendHeader($size, $index, $parity)
-        {
-            if( $size > MAX_STRUCTURED_SYMBOLS ) {
-                throw new Exception('insertStructuredAppendHeader wrong size');
-            }
-            
-            if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS ) {
-                throw new Exception('insertStructuredAppendHeader wrong index');
-            }
-
-            $buf = array($size, $index, $parity);
-            
-            try {
-                $entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf);
-                array_unshift($this->items, $entry);
-                return 0;
-            } catch (Exception $e) {
-                return -1;
-            }
-        }
-
-        //----------------------------------------------------------------------
-        public function calcParity()
-        {
-            $parity = 0;
-            
-            foreach($this->items as $item) {
-                if($item->mode != QR_MODE_STRUCTURE) {
-                    for($i=$item->size-1; $i>=0; $i--) {
-                        $parity ^= $item->data[$i];
-                    }
-                }
-            }
-
-            return $parity;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function checkModeNum($size, $data)
-        {
-            for($i=0; $i<$size; $i++) {
-                if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        //----------------------------------------------------------------------
-        public static function estimateBitsModeNum($size)
-        {
-            $w = (int)$size / 3;
-            $bits = $w * 10;
-            
-            switch($size - $w * 3) {
-                case 1:
-                    $bits += 4;
-                    break;
-                case 2:
-                    $bits += 7;
-                    break;
-                default:
-                    break;
-            }
-
-            return $bits;
-        }
-        
-        //----------------------------------------------------------------------
-        public static $anTable = array(
-            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-            36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
-             0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 44, -1, -1, -1, -1, -1,
-            -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
-            25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
-            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-        );
-        
-        //----------------------------------------------------------------------
-        public static function lookAnTable($c)
-        {
-            return (($c > 127)?-1:self::$anTable[$c]);
-        }
-        
-        //----------------------------------------------------------------------
-        public static function checkModeAn($size, $data)
-        {
-            for($i=0; $i<$size; $i++) {
-                if (self::lookAnTable(ord($data[$i])) == -1) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function estimateBitsModeAn($size)
-        {
-            $w = (int)($size / 2);
-            $bits = $w * 11;
-            
-            if($size & 1) {
-                $bits += 6;
-            }
-
-            return $bits;
-        }
-    
-        //----------------------------------------------------------------------
-        public static function estimateBitsMode8($size)
-        {
-            return $size * 8;
-        }
-        
-        //----------------------------------------------------------------------
-        public function estimateBitsModeKanji($size)
-        {
-            return (int)(($size / 2) * 13);
-        }
-        
-        //----------------------------------------------------------------------
-        public static function checkModeKanji($size, $data)
-        {
-            if($size & 1)
-                return false;
-
-            for($i=0; $i<$size; $i+=2) {
-                $val = (ord($data[$i]) << 8) | ord($data[$i+1]);
-                if( $val < 0x8140 
-                || ($val > 0x9ffc && $val < 0xe040) 
-                || $val > 0xebbf) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        /***********************************************************************
-         * Validation
-         **********************************************************************/
-
-        public static function check($mode, $size, $data)
-        {
-            if($size <= 0) 
-                return false;
-
-            switch($mode) {
-                case QR_MODE_NUM:       return self::checkModeNum($size, $data);   break;
-                case QR_MODE_AN:        return self::checkModeAn($size, $data);    break;
-                case QR_MODE_KANJI:     return self::checkModeKanji($size, $data); break;
-                case QR_MODE_8:         return true; break;
-                case QR_MODE_STRUCTURE: return true; break;
-                
-                default:
-                    break;
-            }
-
-            return false;
-        }
-        
-        
-        //----------------------------------------------------------------------
-        public function estimateBitStreamSize($version)
-        {
-            $bits = 0;
-
-            foreach($this->items as $item) {
-                $bits += $item->estimateBitStreamSizeOfEntry($version);
-            }
-
-            return $bits;
-        }
-        
-        //----------------------------------------------------------------------
-        public function estimateVersion()
-        {
-            $version = 0;
-            $prev = 0;
-            do {
-                $prev = $version;
-                $bits = $this->estimateBitStreamSize($prev);
-                $version = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);
-                if ($version < 0) {
-                    return -1;
-                }
-            } while ($version > $prev);
-
-            return $version;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function lengthOfCode($mode, $version, $bits)
-        {
-            $payload = $bits - 4 - QRspec::lengthIndicator($mode, $version);
-            switch($mode) {
-                case QR_MODE_NUM:
-                    $chunks = (int)($payload / 10);
-                    $remain = $payload - $chunks * 10;
-                    $size = $chunks * 3;
-                    if($remain >= 7) {
-                        $size += 2;
-                    } else if($remain >= 4) {
-                        $size += 1;
-                    }
-                    break;
-                case QR_MODE_AN:
-                    $chunks = (int)($payload / 11);
-                    $remain = $payload - $chunks * 11;
-                    $size = $chunks * 2;
-                    if($remain >= 6) 
-                        $size++;
-                    break;
-                case QR_MODE_8:
-                    $size = (int)($payload / 8);
-                    break;
-                case QR_MODE_KANJI:
-                    $size = (int)(($payload / 13) * 2);
-                    break;
-                case QR_MODE_STRUCTURE:
-                    $size = (int)($payload / 8);
-                    break;
-                default:
-                    $size = 0;
-                    break;
-            }
-            
-            $maxsize = QRspec::maximumWords($mode, $version);
-            if($size < 0) $size = 0;
-            if($size > $maxsize) $size = $maxsize;
-
-            return $size;
-        }
-        
-        //----------------------------------------------------------------------
-        public function createBitStream()
-        {
-            $total = 0;
-
-            foreach($this->items as $item) {
-                $bits = $item->encodeBitStream($this->version);
-                
-                if($bits < 0) 
-                    return -1;
-                    
-                $total += $bits;
-            }
-
-            return $total;
-        }
-        
-        //----------------------------------------------------------------------
-        public function convertData()
-        {
-            $ver = $this->estimateVersion();
-            if($ver > $this->getVersion()) {
-                $this->setVersion($ver);
-            }
-
-            for(;;) {
-                $bits = $this->createBitStream();
-                
-                if($bits < 0) 
-                    return -1;
-                    
-                $ver = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);
-                if($ver < 0) {
-                    throw new Exception('WRONG VERSION');
-                    return -1;
-                } else if($ver > $this->getVersion()) {
-                    $this->setVersion($ver);
-                } else {
-                    break;
-                }
-            }
-
-            return 0;
-        }
-        
-        //----------------------------------------------------------------------
-        public function appendPaddingBit(&$bstream)
-        {
-            $bits = $bstream->size();
-            $maxwords = QRspec::getDataLength($this->version, $this->level);
-            $maxbits = $maxwords * 8;
-
-            if ($maxbits == $bits) {
-                return 0;
-            }
-
-            if ($maxbits - $bits < 5) {
-                return $bstream->appendNum($maxbits - $bits, 0);
-            }
-
-            $bits += 4;
-            $words = (int)(($bits + 7) / 8);
-
-            $padding = new QRbitstream();
-            $ret = $padding->appendNum($words * 8 - $bits + 4, 0);
-            
-            if($ret < 0) 
-                return $ret;
-
-            $padlen = $maxwords - $words;
-            
-            if($padlen > 0) {
-                
-                $padbuf = array();
-                for($i=0; $i<$padlen; $i++) {
-                    $padbuf[$i] = ($i&1)?0x11:0xec;
-                }
-                
-                $ret = $padding->appendBytes($padlen, $padbuf);
-                
-                if($ret < 0)
-                    return $ret;
-                
-            }
-
-            $ret = $bstream->append($padding);
-            
-            return $ret;
-        }
-
-        //----------------------------------------------------------------------
-        public function mergeBitStream()
-        {
-            if($this->convertData() < 0) {
-                return null;
-            }
-
-            $bstream = new QRbitstream();
-            
-            foreach($this->items as $item) {
-                $ret = $bstream->append($item->bstream);
-                if($ret < 0) {
-                    return null;
-                }
-            }
-
-            return $bstream;
-        }
-
-        //----------------------------------------------------------------------
-        public function getBitStream()
-        {
-
-            $bstream = $this->mergeBitStream();
-            
-            if($bstream == null) {
-                return null;
-            }
-            
-            $ret = $this->appendPaddingBit($bstream);
-            if($ret < 0) {
-                return null;
-            }
-
-            return $bstream;
-        }
-        
-        //----------------------------------------------------------------------
-        public function getByteStream()
-        {
-            $bstream = $this->getBitStream();
-            if($bstream == null) {
-                return null;
-            }
-            
-            return $bstream->toByte();
-        }
-    }
-        
-        
-    
-
-
-
-//---- qrbitstream.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Bitstream class
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-     
-    class QRbitstream {
-    
-        public $data = array();
-        
-        //----------------------------------------------------------------------
-        public function size()
-        {
-            return count($this->data);
-        }
-        
-        //----------------------------------------------------------------------
-        public function allocate($setLength)
-        {
-            $this->data = array_fill(0, $setLength, 0);
-            return 0;
-        }
-    
-        //----------------------------------------------------------------------
-        public static function newFromNum($bits, $num)
-        {
-            $bstream = new QRbitstream();
-            $bstream->allocate($bits);
-            
-            $mask = 1 << ($bits - 1);
-            for($i=0; $i<$bits; $i++) {
-                if($num & $mask) {
-                    $bstream->data[$i] = 1;
-                } else {
-                    $bstream->data[$i] = 0;
-                }
-                $mask = $mask >> 1;
-            }
-
-            return $bstream;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function newFromBytes($size, $data)
-        {
-            $bstream = new QRbitstream();
-            $bstream->allocate($size * 8);
-            $p=0;
-
-            for($i=0; $i<$size; $i++) {
-                $mask = 0x80;
-                for($j=0; $j<8; $j++) {
-                    if($data[$i] & $mask) {
-                        $bstream->data[$p] = 1;
-                    } else {
-                        $bstream->data[$p] = 0;
-                    }
-                    $p++;
-                    $mask = $mask >> 1;
-                }
-            }
-
-            return $bstream;
-        }
-        
-        //----------------------------------------------------------------------
-        public function append(QRbitstream $arg)
-        {
-            if (is_null($arg)) {
-                return -1;
-            }
-            
-            if($arg->size() == 0) {
-                return 0;
-            }
-            
-            if($this->size() == 0) {
-                $this->data = $arg->data;
-                return 0;
-            }
-            
-            $this->data = array_values(array_merge($this->data, $arg->data));
-
-            return 0;
-        }
-        
-        //----------------------------------------------------------------------
-        public function appendNum($bits, $num)
-        {
-            if ($bits == 0) 
-                return 0;
-
-            $b = QRbitstream::newFromNum($bits, $num);
-            
-            if(is_null($b))
-                return -1;
-
-            $ret = $this->append($b);
-            unset($b);
-
-            return $ret;
-        }
-
-        //----------------------------------------------------------------------
-        public function appendBytes($size, $data)
-        {
-            if ($size == 0) 
-                return 0;
-
-            $b = QRbitstream::newFromBytes($size, $data);
-            
-            if(is_null($b))
-                return -1;
-
-            $ret = $this->append($b);
-            unset($b);
-
-            return $ret;
-        }
-        
-        //----------------------------------------------------------------------
-        public function toByte()
-        {
-        
-            $size = $this->size();
-
-            if($size == 0) {
-                return array();
-            }
-            
-            $data = array_fill(0, (int)(($size + 7) / 8), 0);
-            $bytes = (int)($size / 8);
-
-            $p = 0;
-            
-            for($i=0; $i<$bytes; $i++) {
-                $v = 0;
-                for($j=0; $j<8; $j++) {
-                    $v = $v << 1;
-                    $v |= $this->data[$p];
-                    $p++;
-                }
-                $data[$i] = $v;
-            }
-            
-            if($size & 7) {
-                $v = 0;
-                for($j=0; $j<($size & 7); $j++) {
-                    $v = $v << 1;
-                    $v |= $this->data[$p];
-                    $p++;
-                }
-                $data[$bytes] = $v;
-            }
-
-            return $data;
-        }
-
-    }
-
-
-
-
-//---- qrsplit.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Input splitting classes
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * The following data / specifications are taken from
- * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
- *  or
- * "Automatic identification and data capture techniques -- 
- *  QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-    class QRsplit {
-
-        public $dataStr = '';
-        public $input;
-        public $modeHint;
-
-        //----------------------------------------------------------------------
-        public function __construct($dataStr, $input, $modeHint) 
-        {
-            $this->dataStr  = $dataStr;
-            $this->input    = $input;
-            $this->modeHint = $modeHint;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function isdigitat($str, $pos)
-        {    
-            if ($pos >= strlen($str))
-                return false;
-            
-            return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9')));
-        }
-        
-        //----------------------------------------------------------------------
-        public static function isalnumat($str, $pos)
-        {
-            if ($pos >= strlen($str))
-                return false;
-                
-            return (QRinput::lookAnTable(ord($str[$pos])) >= 0);
-        }
-
-        //----------------------------------------------------------------------
-        public function identifyMode($pos)
-        {
-            if ($pos >= strlen($this->dataStr)) 
-                return QR_MODE_NUL;
-                
-            $c = $this->dataStr[$pos];
-            
-            if(self::isdigitat($this->dataStr, $pos)) {
-                return QR_MODE_NUM;
-            } else if(self::isalnumat($this->dataStr, $pos)) {
-                return QR_MODE_AN;
-            } else if($this->modeHint == QR_MODE_KANJI) {
-            
-                if ($pos+1 < strlen($this->dataStr)) 
-                {
-                    $d = $this->dataStr[$pos+1];
-                    $word = (ord($c) << 8) | ord($d);
-                    if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) {
-                        return QR_MODE_KANJI;
-                    }
-                }
-            }
-
-            return QR_MODE_8;
-        } 
-        
-        //----------------------------------------------------------------------
-        public function eatNum()
-        {
-            $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
-
-            $p = 0;
-            while(self::isdigitat($this->dataStr, $p)) {
-                $p++;
-            }
-            
-            $run = $p;
-            $mode = $this->identifyMode($p);
-            
-            if($mode == QR_MODE_8) {
-                $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
-                     + QRinput::estimateBitsMode8(1)         // + 4 + l8
-                     - QRinput::estimateBitsMode8($run + 1); // - 4 - l8
-                if($dif > 0) {
-                    return $this->eat8();
-                }
-            }
-            if($mode == QR_MODE_AN) {
-                $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
-                     + QRinput::estimateBitsModeAn(1)        // + 4 + la
-                     - QRinput::estimateBitsModeAn($run + 1);// - 4 - la
-                if($dif > 0) {
-                    return $this->eatAn();
-                }
-            }
-            
-            $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr));
-            if($ret < 0)
-                return -1;
-
-            return $run;
-        }
-        
-        //----------------------------------------------------------------------
-        public function eatAn()
-        {
-            $la = QRspec::lengthIndicator(QR_MODE_AN,  $this->input->getVersion());
-            $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
-
-            $p = 0;
-            
-            while(self::isalnumat($this->dataStr, $p)) {
-                if(self::isdigitat($this->dataStr, $p)) {
-                    $q = $p;
-                    while(self::isdigitat($this->dataStr, $q)) {
-                        $q++;
-                    }
-                    
-                    $dif = QRinput::estimateBitsModeAn($p) // + 4 + la
-                         + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
-                         - QRinput::estimateBitsModeAn($q); // - 4 - la
-                         
-                    if($dif < 0) {
-                        break;
-                    } else {
-                        $p = $q;
-                    }
-                } else {
-                    $p++;
-                }
-            }
-
-            $run = $p;
-
-            if(!self::isalnumat($this->dataStr, $p)) {
-                $dif = QRinput::estimateBitsModeAn($run) + 4 + $la
-                     + QRinput::estimateBitsMode8(1) // + 4 + l8
-                      - QRinput::estimateBitsMode8($run + 1); // - 4 - l8
-                if($dif > 0) {
-                    return $this->eat8();
-                }
-            }
-
-            $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr));
-            if($ret < 0)
-                return -1;
-
-            return $run;
-        }
-        
-        //----------------------------------------------------------------------
-        public function eatKanji()
-        {
-            $p = 0;
-            
-            while($this->identifyMode($p) == QR_MODE_KANJI) {
-                $p += 2;
-            }
-            
-            $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr));
-            if($ret < 0)
-                return -1;
-
-            return $run;
-        }
-
-        //----------------------------------------------------------------------
-        public function eat8()
-        {
-            $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
-            $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
-
-            $p = 1;
-            $dataStrLen = strlen($this->dataStr);
-            
-            while($p < $dataStrLen) {
-                
-                $mode = $this->identifyMode($p);
-                if($mode == QR_MODE_KANJI) {
-                    break;
-                }
-                if($mode == QR_MODE_NUM) {
-                    $q = $p;
-                    while(self::isdigitat($this->dataStr, $q)) {
-                        $q++;
-                    }
-                    $dif = QRinput::estimateBitsMode8($p) // + 4 + l8
-                         + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
-                         - QRinput::estimateBitsMode8($q); // - 4 - l8
-                    if($dif < 0) {
-                        break;
-                    } else {
-                        $p = $q;
-                    }
-                } else if($mode == QR_MODE_AN) {
-                    $q = $p;
-                    while(self::isalnumat($this->dataStr, $q)) {
-                        $q++;
-                    }
-                    $dif = QRinput::estimateBitsMode8($p)  // + 4 + l8
-                         + QRinput::estimateBitsModeAn($q - $p) + 4 + $la
-                         - QRinput::estimateBitsMode8($q); // - 4 - l8
-                    if($dif < 0) {
-                        break;
-                    } else {
-                        $p = $q;
-                    }
-                } else {
-                    $p++;
-                }
-            }
-
-            $run = $p;
-            $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr));
-            
-            if($ret < 0)
-                return -1;
-
-            return $run;
-        }
-
-        //----------------------------------------------------------------------
-        public function splitString()
-        {
-            while (strlen($this->dataStr) > 0)
-            {
-                if($this->dataStr == '')
-                    return 0;
-
-                $mode = $this->identifyMode(0);
-                
-                switch ($mode) {
-                    case QR_MODE_NUM: $length = $this->eatNum(); break;
-                    case QR_MODE_AN:  $length = $this->eatAn(); break;
-                    case QR_MODE_KANJI:
-                        if ($hint == QR_MODE_KANJI)
-                                $length = $this->eatKanji();
-                        else    $length = $this->eat8();
-                        break;
-                    default: $length = $this->eat8(); break;
-                
-                }
-
-                if($length == 0) return 0;
-                if($length < 0)  return -1;
-                
-                $this->dataStr = substr($this->dataStr, $length);
-            }
-        }
-
-        //----------------------------------------------------------------------
-        public function toUpper()
-        {
-            $stringLen = strlen($this->dataStr);
-            $p = 0;
-            
-            while ($p<$stringLen) {
-                $mode = self::identifyMode(substr($this->dataStr, $p), $this->modeHint);
-                if($mode == QR_MODE_KANJI) {
-                    $p += 2;
-                } else {
-                    if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) {
-                        $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);
-                    }
-                    $p++;
-                }
-            }
-
-            return $this->dataStr;
-        }
-
-        //----------------------------------------------------------------------
-        public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true)
-        {
-            if(is_null($string) || $string == '\0' || $string == '') {
-                throw new Exception('empty string!!!');
-            }
-
-            $split = new QRsplit($string, $input, $modeHint);
-            
-            if(!$casesensitive)
-                $split->toUpper();
-                
-            return $split->splitString();
-        }
-    }
-
-
-
-//---- qrrscode.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Reed-Solomon error correction support
- * 
- * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
- * (libfec is released under the GNU Lesser General Public License.)
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-    class QRrsItem {
-    
-        public $mm;                  // Bits per symbol 
-        public $nn;                  // Symbols per block (= (1<<mm)-1) 
-        public $alpha_to = array();  // log lookup table 
-        public $index_of = array();  // Antilog lookup table 
-        public $genpoly = array();   // Generator polynomial 
-        public $nroots;              // Number of generator roots = number of parity symbols 
-        public $fcr;                 // First consecutive root, index form 
-        public $prim;                // Primitive element, index form 
-        public $iprim;               // prim-th root of 1, index form 
-        public $pad;                 // Padding bytes in shortened block 
-        public $gfpoly;
-    
-        //----------------------------------------------------------------------
-        public function modnn($x)
-        {
-            while ($x >= $this->nn) {
-                $x -= $this->nn;
-                $x = ($x >> $this->mm) + ($x & $this->nn);
-            }
-            
-            return $x;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
-        {
-            // Common code for intializing a Reed-Solomon control block (char or int symbols)
-            // Copyright 2004 Phil Karn, KA9Q
-            // May be used under the terms of the GNU Lesser General Public License (LGPL)
-
-            $rs = null;
-            
-            // Check parameter ranges
-            if($symsize < 0 || $symsize > 8)                     return $rs;
-            if($fcr < 0 || $fcr >= (1<<$symsize))                return $rs;
-            if($prim <= 0 || $prim >= (1<<$symsize))             return $rs;
-            if($nroots < 0 || $nroots >= (1<<$symsize))          return $rs; // Can't have more roots than symbol values!
-            if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding
-
-            $rs = new QRrsItem();
-            $rs->mm = $symsize;
-            $rs->nn = (1<<$symsize)-1;
-            $rs->pad = $pad;
-
-            $rs->alpha_to = array_fill(0, $rs->nn+1, 0);
-            $rs->index_of = array_fill(0, $rs->nn+1, 0);
-          
-            // PHP style macro replacement ;)
-            $NN =& $rs->nn;
-            $A0 =& $NN;
-            
-            // Generate Galois field lookup tables
-            $rs->index_of[0] = $A0; // log(zero) = -inf
-            $rs->alpha_to[$A0] = 0; // alpha**-inf = 0
-            $sr = 1;
-          
-            for($i=0; $i<$rs->nn; $i++) {
-                $rs->index_of[$sr] = $i;
-                $rs->alpha_to[$i] = $sr;
-                $sr <<= 1;
-                if($sr & (1<<$symsize)) {
-                    $sr ^= $gfpoly;
-                }
-                $sr &= $rs->nn;
-            }
-            
-            if($sr != 1){
-                // field generator polynomial is not primitive!
-                $rs = NULL;
-                return $rs;
-            }
-
-            /* Form RS code generator polynomial from its roots */
-            $rs->genpoly = array_fill(0, $nroots+1, 0);
-        
-            $rs->fcr = $fcr;
-            $rs->prim = $prim;
-            $rs->nroots = $nroots;
-            $rs->gfpoly = $gfpoly;
-
-            /* Find prim-th root of 1, used in decoding */
-            for($iprim=1;($iprim % $prim) != 0;$iprim += $rs->nn)
-            ; // intentional empty-body loop!
-            
-            $rs->iprim = (int)($iprim / $prim);
-            $rs->genpoly[0] = 1;
-            
-            for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) {
-                $rs->genpoly[$i+1] = 1;
-
-                // Multiply rs->genpoly[] by  @**(root + x)
-                for ($j = $i; $j > 0; $j--) {
-                    if ($rs->genpoly[$j] != 0) {
-                        $rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)];
-                    } else {
-                        $rs->genpoly[$j] = $rs->genpoly[$j-1];
-                    }
-                }
-                // rs->genpoly[0] can never be zero
-                $rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)];
-            }
-            
-            // convert rs->genpoly[] to index form for quicker encoding
-            for ($i = 0; $i <= $nroots; $i++)
-                $rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]];
-
-            return $rs;
-        }
-        
-        //----------------------------------------------------------------------
-        public function encode_rs_char($data, &$parity)
-        {
-            $MM       =& $this->mm;
-            $NN       =& $this->nn;
-            $ALPHA_TO =& $this->alpha_to;
-            $INDEX_OF =& $this->index_of;
-            $GENPOLY  =& $this->genpoly;
-            $NROOTS   =& $this->nroots;
-            $FCR      =& $this->fcr;
-            $PRIM     =& $this->prim;
-            $IPRIM    =& $this->iprim;
-            $PAD      =& $this->pad;
-            $A0       =& $NN;
-
-            $parity = array_fill(0, $NROOTS, 0);
-
-            for($i=0; $i< ($NN-$NROOTS-$PAD); $i++) {
-                
-                $feedback = $INDEX_OF[$data[$i] ^ $parity[0]];
-                if($feedback != $A0) {      
-                    // feedback term is non-zero
-            
-                    // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
-                    // always be for the polynomials constructed by init_rs()
-                    $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback);
-            
-                    for($j=1;$j<$NROOTS;$j++) {
-                        $parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS-$j])];
-                    }
-                }
-                
-                // Shift 
-                array_shift($parity);
-                if($feedback != $A0) {
-                    array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]);
-                } else {
-                    array_push($parity, 0);
-                }
-            }
-        }
-    }
-    
-    //##########################################################################
-    
-    class QRrs {
-    
-        public static $items = array();
-        
-        //----------------------------------------------------------------------
-        public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
-        {
-            foreach(self::$items as $rs) {
-                if($rs->pad != $pad)       continue;
-                if($rs->nroots != $nroots) continue;
-                if($rs->mm != $symsize)    continue;
-                if($rs->gfpoly != $gfpoly) continue;
-                if($rs->fcr != $fcr)       continue;
-                if($rs->prim != $prim)     continue;
-
-                return $rs;
-            }
-
-            $rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad);
-            array_unshift(self::$items, $rs);
-
-            return $rs;
-        }
-    }
-
-
-
-//---- qrmask.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Masking
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-	define('N1', 3);
-	define('N2', 3);
-	define('N3', 40);
-	define('N4', 10);
-
-	class QRmask {
-	
-		public $runLength = array();
-		
-		//----------------------------------------------------------------------
-		public function __construct() 
-        {
-            $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0);
-        }
-        
-        //----------------------------------------------------------------------
-        public function writeFormatInformation($width, &$frame, $mask, $level)
-        {
-            $blacks = 0;
-            $format =  QRspec::getFormatInfo($mask, $level);
-
-            for($i=0; $i<8; $i++) {
-                if($format & 1) {
-                    $blacks += 2;
-                    $v = 0x85;
-                } else {
-                    $v = 0x84;
-                }
-                
-                $frame[8][$width - 1 - $i] = chr($v);
-                if($i < 6) {
-                    $frame[$i][8] = chr($v);
-                } else {
-                    $frame[$i + 1][8] = chr($v);
-                }
-                $format = $format >> 1;
-            }
-            
-            for($i=0; $i<7; $i++) {
-                if($format & 1) {
-                    $blacks += 2;
-                    $v = 0x85;
-                } else {
-                    $v = 0x84;
-                }
-                
-                $frame[$width - 7 + $i][8] = chr($v);
-                if($i == 0) {
-                    $frame[8][7] = chr($v);
-                } else {
-                    $frame[8][6 - $i] = chr($v);
-                }
-                
-                $format = $format >> 1;
-            }
-
-            return $blacks;
-        }
-        
-        //----------------------------------------------------------------------
-        public function mask0($x, $y) { return ($x+$y)&1;                       }
-        public function mask1($x, $y) { return ($y&1);                          }
-        public function mask2($x, $y) { return ($x%3);                          }
-        public function mask3($x, $y) { return ($x+$y)%3;                       }
-        public function mask4($x, $y) { return (((int)($y/2))+((int)($x/3)))&1; }
-        public function mask5($x, $y) { return (($x*$y)&1)+($x*$y)%3;           }
-        public function mask6($x, $y) { return ((($x*$y)&1)+($x*$y)%3)&1;       }
-        public function mask7($x, $y) { return ((($x*$y)%3)+(($x+$y)&1))&1;     }
-        
-        //----------------------------------------------------------------------
-        private function generateMaskNo($maskNo, $width, $frame)
-        {
-            $bitMask = array_fill(0, $width, array_fill(0, $width, 0));
-            
-            for($y=0; $y<$width; $y++) {
-                for($x=0; $x<$width; $x++) {
-                    if(ord($frame[$y][$x]) & 0x80) {
-                        $bitMask[$y][$x] = 0;
-                    } else {
-                        $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y);
-                        $bitMask[$y][$x] = ($maskFunc == 0)?1:0;
-                    }
-                    
-                }
-            }
-            
-            return $bitMask;
-        }
-        
-        //----------------------------------------------------------------------
-        public static function serial($bitFrame)
-        {
-            $codeArr = array();
-            
-            foreach ($bitFrame as $line)
-                $codeArr[] = join('', $line);
-                
-            return gzcompress(join("\n", $codeArr), 9);
-        }
-        
-        //----------------------------------------------------------------------
-        public static function unserial($code)
-        {
-            $codeArr = array();
-            
-            $codeLines = explode("\n", gzuncompress($code));
-            foreach ($codeLines as $line)
-                $codeArr[] = str_split($line);
-            
-            return $codeArr;
-        }
-        
-        //----------------------------------------------------------------------
-        public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false) 
-        {
-            $b = 0;
-            $bitMask = array();
-            
-            $fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat';
-
-            if (QR_CACHEABLE) {
-                if (file_exists($fileName)) {
-                    $bitMask = self::unserial(file_get_contents($fileName));
-                } else {
-                    $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
-                    if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo))
-                        mkdir(QR_CACHE_DIR.'mask_'.$maskNo);
-                    file_put_contents($fileName, self::serial($bitMask));
-                }
-            } else {
-                $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
-            }
-
-            if ($maskGenOnly)
-                return;
-                
-            $d = $s;
-
-            for($y=0; $y<$width; $y++) {
-                for($x=0; $x<$width; $x++) {
-                    if($bitMask[$y][$x] == 1) {
-                        $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]);
-                    }
-                    $b += (int)(ord($d[$y][$x]) & 1);
-                }
-            }
-
-            return $b;
-        }
-        
-        //----------------------------------------------------------------------
-        public function makeMask($width, $frame, $maskNo, $level)
-        {
-            $masked = array_fill(0, $width, str_repeat("\0", $width));
-            $this->makeMaskNo($maskNo, $width, $frame, $masked);
-            $this->writeFormatInformation($width, $masked, $maskNo, $level);
-       
-            return $masked;
-        }
-        
-        //----------------------------------------------------------------------
-        public function calcN1N3($length)
-        {
-            $demerit = 0;
-
-            for($i=0; $i<$length; $i++) {
-                
-                if($this->runLength[$i] >= 5) {
-                    $demerit += (N1 + ($this->runLength[$i] - 5));
-                }
-                if($i & 1) {
-                    if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) {
-                        $fact = (int)($this->runLength[$i] / 3);
-                        if(($this->runLength[$i-2] == $fact) &&
-                           ($this->runLength[$i-1] == $fact) &&
-                           ($this->runLength[$i+1] == $fact) &&
-                           ($this->runLength[$i+2] == $fact)) {
-                            if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) {
-                                $demerit += N3;
-                            } else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) {
-                                $demerit += N3;
-                            }
-                        }
-                    }
-                }
-            }
-            return $demerit;
-        }
-        
-        //----------------------------------------------------------------------
-        public function evaluateSymbol($width, $frame)
-        {
-            $head = 0;
-            $demerit = 0;
-
-            for($y=0; $y<$width; $y++) {
-                $head = 0;
-                $this->runLength[0] = 1;
-                
-                $frameY = $frame[$y];
-                
-                if ($y>0)
-                    $frameYM = $frame[$y-1];
-                
-                for($x=0; $x<$width; $x++) {
-                    if(($x > 0) && ($y > 0)) {
-                        $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]);
-                        $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]);
-                        
-                        if(($b22 | ($w22 ^ 1))&1) {                                                                     
-                            $demerit += N2;
-                        }
-                    }
-                    if(($x == 0) && (ord($frameY[$x]) & 1)) {
-                        $this->runLength[0] = -1;
-                        $head = 1;
-                        $this->runLength[$head] = 1;
-                    } else if($x > 0) {
-                        if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) {
-                            $head++;
-                            $this->runLength[$head] = 1;
-                        } else {
-                            $this->runLength[$head]++;
-                        }
-                    }
-                }
-    
-                $demerit += $this->calcN1N3($head+1);
-            }
-
-            for($x=0; $x<$width; $x++) {
-                $head = 0;
-                $this->runLength[0] = 1;
-                
-                for($y=0; $y<$width; $y++) {
-                    if($y == 0 && (ord($frame[$y][$x]) & 1)) {
-                        $this->runLength[0] = -1;
-                        $head = 1;
-                        $this->runLength[$head] = 1;
-                    } else if($y > 0) {
-                        if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) {
-                            $head++;
-                            $this->runLength[$head] = 1;
-                        } else {
-                            $this->runLength[$head]++;
-                        }
-                    }
-                }
-            
-                $demerit += $this->calcN1N3($head+1);
-            }
-
-            return $demerit;
-        }
-        
-        
-        //----------------------------------------------------------------------
-        public function mask($width, $frame, $level)
-        {
-            $minDemerit = PHP_INT_MAX;
-            $bestMaskNum = 0;
-            $bestMask = array();
-            
-            $checked_masks = array(0,1,2,3,4,5,6,7);
-            
-            if (QR_FIND_FROM_RANDOM !== false) {
-            
-                $howManuOut = 8-(QR_FIND_FROM_RANDOM % 9);
-                for ($i = 0; $i <  $howManuOut; $i++) {
-                    $remPos = rand (0, count($checked_masks)-1);
-                    unset($checked_masks[$remPos]);
-                    $checked_masks = array_values($checked_masks);
-                }
-            
-            }
-            
-            $bestMask = $frame;
-             
-            foreach($checked_masks as $i) {
-                $mask = array_fill(0, $width, str_repeat("\0", $width));
-
-                $demerit = 0;
-                $blacks = 0;
-                $blacks  = $this->makeMaskNo($i, $width, $frame, $mask);
-                $blacks += $this->writeFormatInformation($width, $mask, $i, $level);
-                $blacks  = (int)(100 * $blacks / ($width * $width));
-                $demerit = (int)((int)(abs($blacks - 50) / 5) * N4);
-                $demerit += $this->evaluateSymbol($width, $mask);
-                
-                if($demerit < $minDemerit) {
-                    $minDemerit = $demerit;
-                    $bestMask = $mask;
-                    $bestMaskNum = $i;
-                }
-            }
-            
-            return $bestMask;
-        }
-        
-        //----------------------------------------------------------------------
-    }
-
-
-
-
-//---- qrencode.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Main encoder classes.
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- 
-    class QRrsblock {
-        public $dataLength;
-        public $data = array();
-        public $eccLength;
-        public $ecc = array();
-        
-        public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs)
-        {
-            $rs->encode_rs_char($data, $ecc);
-        
-            $this->dataLength = $dl;
-            $this->data = $data;
-            $this->eccLength = $el;
-            $this->ecc = $ecc;
-        }
-    };
-    
-    //##########################################################################
-
-    class QRrawcode {
-        public $version;
-        public $datacode = array();
-        public $ecccode = array();
-        public $blocks;
-        public $rsblocks = array(); //of RSblock
-        public $count;
-        public $dataLength;
-        public $eccLength;
-        public $b1;
-        
-        //----------------------------------------------------------------------
-        public function __construct(QRinput $input)
-        {
-            $spec = array(0,0,0,0,0);
-            
-            $this->datacode = $input->getByteStream();
-            if(is_null($this->datacode)) {
-                throw new Exception('null imput string');
-            }
-
-            QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec);
-
-            $this->version = $input->getVersion();
-            $this->b1 = QRspec::rsBlockNum1($spec);
-            $this->dataLength = QRspec::rsDataLength($spec);
-            $this->eccLength = QRspec::rsEccLength($spec);
-            $this->ecccode = array_fill(0, $this->eccLength, 0);
-            $this->blocks = QRspec::rsBlockNum($spec);
-            
-            $ret = $this->init($spec);
-            if($ret < 0) {
-                throw new Exception('block alloc error');
-                return null;
-            }
-
-            $this->count = 0;
-        }
-        
-        //----------------------------------------------------------------------
-        public function init(array $spec)
-        {
-            $dl = QRspec::rsDataCodes1($spec);
-            $el = QRspec::rsEccCodes1($spec);
-            $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
-            
-
-            $blockNo = 0;
-            $dataPos = 0;
-            $eccPos = 0;
-            for($i=0; $i<QRspec::rsBlockNum1($spec); $i++) {
-                $ecc = array_slice($this->ecccode,$eccPos);
-                $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el,  $ecc, $rs);
-                $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
-                
-                $dataPos += $dl;
-                $eccPos += $el;
-                $blockNo++;
-            }
-
-            if(QRspec::rsBlockNum2($spec) == 0)
-                return 0;
-
-            $dl = QRspec::rsDataCodes2($spec);
-            $el = QRspec::rsEccCodes2($spec);
-            $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
-            
-            if($rs == NULL) return -1;
-            
-            for($i=0; $i<QRspec::rsBlockNum2($spec); $i++) {
-                $ecc = array_slice($this->ecccode,$eccPos);
-                $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
-                $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
-                
-                $dataPos += $dl;
-                $eccPos += $el;
-                $blockNo++;
-            }
-
-            return 0;
-        }
-        
-        //----------------------------------------------------------------------
-        public function getCode()
-        {
-            $ret;
-
-            if($this->count < $this->dataLength) {
-                $row = $this->count % $this->blocks;
-                $col = $this->count / $this->blocks;
-                if($col >= $this->rsblocks[0]->dataLength) {
-                    $row += $this->b1;
-                }
-                $ret = $this->rsblocks[$row]->data[$col];
-            } else if($this->count < $this->dataLength + $this->eccLength) {
-                $row = ($this->count - $this->dataLength) % $this->blocks;
-                $col = ($this->count - $this->dataLength) / $this->blocks;
-                $ret = $this->rsblocks[$row]->ecc[$col];
-            } else {
-                return 0;
-            }
-            $this->count++;
-            
-            return $ret;
-        }
-    }
-
-    //##########################################################################
-    
-    class QRcode {
-    
-        public $version;
-        public $width;
-        public $data; 
-        
-        //----------------------------------------------------------------------
-        public function encodeMask(QRinput $input, $mask)
-        {
-            if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) {
-                throw new Exception('wrong version');
-            }
-            if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) {
-                throw new Exception('wrong level');
-            }
-
-            $raw = new QRrawcode($input);
-            
-            QRtools::markTime('after_raw');
-            
-            $version = $raw->version;
-            $width = QRspec::getWidth($version);
-            $frame = QRspec::newFrame($version);
-            
-            $filler = new FrameFiller($width, $frame);
-            if(is_null($filler)) {
-                return NULL;
-            }
-
-            // inteleaved data and ecc codes
-            for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) {
-                $code = $raw->getCode();
-                $bit = 0x80;
-                for($j=0; $j<8; $j++) {
-                    $addr = $filler->next();
-                    $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0));
-                    $bit = $bit >> 1;
-                }
-            }
-            
-            QRtools::markTime('after_filler');
-            
-            unset($raw);
-            
-            // remainder bits
-            $j = QRspec::getRemainder($version);
-            for($i=0; $i<$j; $i++) {
-                $addr = $filler->next();
-                $filler->setFrameAt($addr, 0x02);
-            }
-            
-            $frame = $filler->frame;
-            unset($filler);
-            
-            
-            // masking
-            $maskObj = new QRmask();
-            if($mask < 0) {
-            
-                if (QR_FIND_BEST_MASK) {
-                    $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel());
-                } else {
-                    $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel());
-                }
-            } else {
-                $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel());
-            }
-            
-            if($masked == NULL) {
-                return NULL;
-            }
-            
-            QRtools::markTime('after_mask');
-            
-            $this->version = $version;
-            $this->width = $width;
-            $this->data = $masked;
-            
-            return $this;
-        }
-    
-        //----------------------------------------------------------------------
-        public function encodeInput(QRinput $input)
-        {
-            return $this->encodeMask($input, -1);
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeString8bit($string, $version, $level)
-        {
-            if(string == NULL) {
-                throw new Exception('empty string!');
-                return NULL;
-            }
-
-            $input = new QRinput($version, $level);
-            if($input == NULL) return NULL;
-
-            $ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string));
-            if($ret < 0) {
-                unset($input);
-                return NULL;
-            }
-            return $this->encodeInput($input);
-        }
-
-        //----------------------------------------------------------------------
-        public function encodeString($string, $version, $level, $hint, $casesensitive)
-        {
-
-            if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) {
-                throw new Exception('bad hint');
-                return NULL;
-            }
-
-            $input = new QRinput($version, $level);
-            if($input == NULL) return NULL;
-
-            $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive);
-            if($ret < 0) {
-                return NULL;
-            }
-
-            return $this->encodeInput($input);
-        }
-        
-        //----------------------------------------------------------------------
-        public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false) 
-        {
-            $enc = QRencode::factory($level, $size, $margin);
-            return $enc->encodePNG($text, $outfile, $saveandprint=false);
-        }
-
-        //----------------------------------------------------------------------
-        public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) 
-        {
-            $enc = QRencode::factory($level, $size, $margin);
-            return $enc->encode($text, $outfile);
-        }
-
-        //----------------------------------------------------------------------
-        public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) 
-        {
-            $enc = QRencode::factory($level, $size, $margin);
-            return $enc->encodeRAW($text, $outfile);
-        }
-    }
-    
-    //##########################################################################
-    
-    class FrameFiller {
-    
-        public $width;
-        public $frame;
-        public $x;
-        public $y;
-        public $dir;
-        public $bit;
-        
-        //----------------------------------------------------------------------
-        public function __construct($width, &$frame)
-        {
-            $this->width = $width;
-            $this->frame = $frame;
-            $this->x = $width - 1;
-            $this->y = $width - 1;
-            $this->dir = -1;
-            $this->bit = -1;
-        }
-        
-        //----------------------------------------------------------------------
-        public function setFrameAt($at, $val)
-        {
-            $this->frame[$at['y']][$at['x']] = chr($val);
-        }
-        
-        //----------------------------------------------------------------------
-        public function getFrameAt($at)
-        {
-            return ord($this->frame[$at['y']][$at['x']]);
-        }
-        
-        //----------------------------------------------------------------------
-        public function next()
-        {
-            do {
-            
-                if($this->bit == -1) {
-                    $this->bit = 0;
-                    return array('x'=>$this->x, 'y'=>$this->y);
-                }
-
-                $x = $this->x;
-                $y = $this->y;
-                $w = $this->width;
-
-                if($this->bit == 0) {
-                    $x--;
-                    $this->bit++;
-                } else {
-                    $x++;
-                    $y += $this->dir;
-                    $this->bit--;
-                }
-
-                if($this->dir < 0) {
-                    if($y < 0) {
-                        $y = 0;
-                        $x -= 2;
-                        $this->dir = 1;
-                        if($x == 6) {
-                            $x--;
-                            $y = 9;
-                        }
-                    }
-                } else {
-                    if($y == $w) {
-                        $y = $w - 1;
-                        $x -= 2;
-                        $this->dir = -1;
-                        if($x == 6) {
-                            $x--;
-                            $y -= 8;
-                        }
-                    }
-                }
-                if($x < 0 || $y < 0) return null;
-
-                $this->x = $x;
-                $this->y = $y;
-
-            } while(ord($this->frame[$y][$x]) & 0x80);
-                        
-            return array('x'=>$x, 'y'=>$y);
-        }
-        
-    } ;
-    
-    //##########################################################################    
-    
-    class QRencode {
-    
-        public $casesensitive = true;
-        public $eightbit = false;
-        
-        public $version = 0;
-        public $size = 3;
-        public $margin = 4;
-        
-        public $structured = 0; // not supported yet
-        
-        public $level = QR_ECLEVEL_L;
-        public $hint = QR_MODE_8;
-        
-        //----------------------------------------------------------------------
-        public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4)
-        {
-            $enc = new QRencode();
-            $enc->size = $size;
-            $enc->margin = $margin;
-            
-            switch ($level.'') {
-                case '0':
-                case '1':
-                case '2':
-                case '3':
-                        $enc->level = $level;
-                    break;
-                case 'l':
-                case 'L':
-                        $enc->level = QR_ECLEVEL_L;
-                    break;
-                case 'm':
-                case 'M':
-                        $enc->level = QR_ECLEVEL_M;
-                    break;
-                case 'q':
-                case 'Q':
-                        $enc->level = QR_ECLEVEL_Q;
-                    break;
-                case 'h':
-                case 'H':
-                        $enc->level = QR_ECLEVEL_H;
-                    break;
-            }
-            
-            return $enc;
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodeRAW($intext, $outfile = false) 
-        {
-            $code = new QRcode();
-
-            if($this->eightbit) {
-                $code->encodeString8bit($intext, $this->version, $this->level);
-            } else {
-                $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
-            }
-            
-            return $code->data;
-        }
-
-        //----------------------------------------------------------------------
-        public function encode($intext, $outfile = false) 
-        {
-            $code = new QRcode();
-
-            if($this->eightbit) {
-                $code->encodeString8bit($intext, $this->version, $this->level);
-            } else {
-                $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
-            }
-            
-            QRtools::markTime('after_encode');
-            
-            if ($outfile!== false) {
-                file_put_contents($outfile, join("\n", QRtools::binarize($code->data)));
-            } else {
-                return QRtools::binarize($code->data);
-            }
-        }
-        
-        //----------------------------------------------------------------------
-        public function encodePNG($intext, $outfile = false,$saveandprint=false) 
-        {
-            try {
-            
-                ob_start();
-                $tab = $this->encode($intext);
-                $err = ob_get_contents();
-                ob_end_clean();
-                
-                if ($err != '')
-                    QRtools::log($outfile, $err);
-                
-                $maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin));
-                
-                QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint);
-            
-            } catch (Exception $e) {
-            
-                QRtools::log($outfile, $e->getMessage());
-            
-            }
-        }
-    }
-
-
diff --git a/leed/qrcode.php b/leed/qrcode.php
deleted file mode 100644
index 9f3d9bbdc1ccea8eb769d603e1f2bb9b8f3ae987..0000000000000000000000000000000000000000
--- a/leed/qrcode.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-
-require_once('common.php');
-if (empty($myUser)) exit();
-
-require_once('phpqrcode.php');
-
-$methode = array_keys($_REQUEST)[0];
-switch($methode) {
-    case 'qr': # qrcode.php?qr&label=A&user=B&key=C
-        Functions::chargeVarRequest('label', 'user', 'key', 'issuer', 'algorithm', 'digits', 'period');
-        if (empty($key)) {
-            $key = "**********";
-        }
-        $qrCode = "otpauth://totp/{$label}:{$user}?secret={$key}";
-        foreach (array('issuer', 'algorithm', 'digits', 'period') as $champ)
-            if (!empty(${$champ}))
-                $qrCode.="&{$champ}={${$champ}}";
-        break;
-    case 'txt': # qrcode.php?txt&TEXTE
-        $qrCode = substr($_SERVER['QUERY_STRING'], 1+strlen($methode));
-        break;
-    default:
-        $qrCode = '';
-}
-
-Functions::chargeVarRequest('_qrSize', '_qrMargin');
-if (empty($_qrSize))   $_qrSize   = 3;
-if (empty($_qrMargin)) $_qrMargin = 4;
-
-QRcode::png($qrCode, false, 'QR_LEVEL_H', $_qrSize, $_qrMargin);
diff --git a/leed/settings.php b/leed/settings.php
deleted file mode 100644
index a43f8761225b460964657638770de1f1bc5419e7..0000000000000000000000000000000000000000
--- a/leed/settings.php
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-
-/*
- @nom: settings
- @auteur: Idleman (http://blog.idleman.fr)
- @description: Page de gestion de toutes les préférences/configurations administrateur
- */
-
-require_once('header.php');
-
-$tpl->assign('serviceUrl', rtrim($_SERVER['HTTP_HOST'].$cookiedir,'/'));
-
-$logger = new Logger('settings');
-$tpl->assign('logs',$logger->flushLogs());
-
-// gestion de la langue
-$tpl->assign('languageList',$i18n->translatedLanguages);
-$tpl->assign('currentLanguage',$configurationManager->get('language'));
-
-$wrongLogin = !empty($wrongLogin);
-$tpl->assign('wrongLogin',$wrongLogin);
-
-// gestion des thèmes
-$themesDir = 'templates/';
-$dirs = scandir($themesDir);
-foreach($dirs as $dir){
-    if(is_dir($themesDir.$dir) && !in_array($dir,array(".","..")) ){
-        $themeList[]=$dir;
-    }
-}
-sort($themeList);
-$tpl->assign('themeList',$themeList);
-$tpl->assign('currentTheme',$configurationManager->get('theme'));
-
-//autres variables de configuration
-$tpl->assign('feeds',$feedManager->populate('name'));
-$tpl->assign('folders',$folderManager->populate('name'));
-$tpl->assign('synchronisationType',$configurationManager->get('synchronisationType'));
-$tpl->assign('synchronisationEnableCache',$configurationManager->get('synchronisationEnableCache'));
-$tpl->assign('synchronisationForceFeed',$configurationManager->get('synchronisationForceFeed'));
-$tpl->assign('articleDisplayLink', $configurationManager->get('articleDisplayLink'));
-$tpl->assign('articleDisplayDate', $configurationManager->get('articleDisplayDate'));
-$tpl->assign('articleDisplayAuthor', $configurationManager->get('articleDisplayAuthor'));
-$tpl->assign('articleDisplayHomeSort', $configurationManager->get('articleDisplayHomeSort'));
-$tpl->assign('articleDisplayFolderSort', $configurationManager->get('articleDisplayFolderSort'));
-$tpl->assign('articleDisplayMode', $configurationManager->get('articleDisplayMode'));
-$tpl->assign('optionFeedIsVerbose', $configurationManager->get('optionFeedIsVerbose'));
-
-$tpl->assign('otpEnabled', $configurationManager->get('otpEnabled'));
-
-//Suppression de l'état des plugins inexistants
-Plugin::pruneStates();
-
-//Récuperation des plugins
-$tpl->assign('plugins',Plugin::getAll());
-
-$view = "settings";
-require_once('footer.php'); ?>
diff --git a/leed/translations.js.php b/leed/translations.js.php
deleted file mode 100644
index 377d6007a71c8bf47878bedbd22920f3d803ba96..0000000000000000000000000000000000000000
--- a/leed/translations.js.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php
-require_once('header.php');
-header('Content-Type: application/javascript; charset=utf-8');
-echo "var  i18n = {$i18n_js};";
diff --git a/leed/update-1.5.sql b/leed/update-1.5.sql
deleted file mode 100644
index 08e9f72efd5b0fac5613e83323d2043c48d97b0b..0000000000000000000000000000000000000000
--- a/leed/update-1.5.sql
+++ /dev/null
@@ -1,23 +0,0 @@
-/* #############
-###  MISE À JOUR Base de données de Leed pour fonctionnement en v1.5
-
-Conseils :
-- Avant d'effectuer la mise à jour, sauvegardez votre BDD et exportez vos flux en OPML.
-- Attention : "leed_" est à remplacer par votre préfix de table.
-- Ce fichier est à supprimer après installation.
-
-Description :
-- Les requêtes suivantes sont a exécuter sur votre Base de données Leed avec phpMyAdmin par exemple
-
-############### */
-
--- Mise à jour index Table des Event
-ALTER TABLE `leed_event` ADD KEY `indexfeed` (`feed`);
-ALTER TABLE `leed_event` ADD KEY `indexunread` (`unread`);
-ALTER TABLE `leed_event` ADD KEY `indexfavorite` (`favorite`);
-
--- Mise à jour index Table des Feed
-ALTER TABLE `leed_feed` ADD KEY `indexfolder` (`folder`);
-
--- Mise à jour table Event pour la synchronisation des flux (OBLIGATOIRE)
-ALTER TABLE `leed_event` ADD `syncId` INT UNSIGNED NOT NULL;
\ No newline at end of file
diff --git a/leed/update-r93.php b/leed/update-r93.php
deleted file mode 100644
index d0343d20df8aa78f3794ff677fbe83bbc7464587..0000000000000000000000000000000000000000
--- a/leed/update-r93.php
+++ /dev/null
@@ -1,85 +0,0 @@
-<?php
-error_reporting(E_ALL);
-@set_time_limit(0);
-
-/**
- *  met à jour la BDD de la rev92 à la rev 93
- *  Leed doit déjà être installé
- *  auteur : alefburzmali
- */
-
-ob_start();
-require 'constant.php';
-
-// connexion
-$mysql = new MySQLi(MYSQL_HOST,MYSQL_LOGIN,MYSQL_MDP,MYSQL_BDD);
-
-$tables = array(
-    'c' => MYSQL_PREFIX.'configuration',
-    'e' => MYSQL_PREFIX.'event',
-    'f' => MYSQL_PREFIX.'feed',
-    'd' => MYSQL_PREFIX.'folder',
-    'u' => MYSQL_PREFIX.'user',
-);
-
-// on convertit toutes les tables
-foreach ($tables as $tb)
-{
-    echo '<br>conversion de la structure de la table '.$tb.' ... ';
-    ob_flush(); flush();
-    if (!$mysql->query('ALTER TABLE '.$tb.' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci, ENGINE=InnoDB'))
-    {
-        echo 'erreur !<br>';
-        print_r($mysql->error_list);
-        ob_flush(); flush();
-        die(1);
-    }
-    echo 'ok';
-}
-
-// on passe la connexion en utf-8 pour traiter les données
-$mysql->query('SET NAMES utf8');
-
-// maintenant on va récupérer toutes les tables pour faire html_entity_decode
-function convert($table, $champs)
-{
-    global $mysql;
-    echo '<br>conversion des données de la table '.$table.' ... ';
-    ob_flush(); flush();
-
-    $res = $mysql->query('SELECT * FROM '.$table);
-    if ($res)
-    {
-        while ($row = $res->fetch_assoc())
-        {
-            $sql = 'UPDATE '.$table.' SET ';
-            $first = true;
-            foreach ($champs as $c)
-            {
-                $row[$c] = html_entity_decode($row[$c]);
-                $sql .= ($first?'':', '). $c .'="'.$mysql->real_escape_string($row[$c]).'"';
-                $first = false;
-            }
-            $sql .= ' WHERE id = '.$row['id'];
-            if (!$mysql->query($sql))
-            {
-                echo 'erreur champ '.$row['id'].'<br>';
-                print_r($mysql->error_list);
-
-                echo '<br>on continue ... ';
-                ob_flush(); flush();
-            }
-        }
-        echo 'ok';
-        $res->free();
-    }
-}
-
-// evenements
-convert($tables['e'], array('title','creator','content','description'));
-// feed
-convert($tables['f'], array('name','description'));
-// folder
-convert($tables['d'], array('name'));
-
-echo '<br>Conversion terminée';
diff --git a/leed/updates/00001-Update-20140213.sql b/leed/updates/00001-Update-20140213.sql
deleted file mode 100644
index 6457092b8da5fda17192d5efc399f7211b2ca094..0000000000000000000000000000000000000000
--- a/leed/updates/00001-Update-20140213.sql
+++ /dev/null
@@ -1,20 +0,0 @@
---######################################################################################################
---#####
---#####     MISE À JOUR Base de données de Leed
---#####			Date : 13/02/2014
---#####			Version Leed : v1.6
---#####
---#####				Préfixe des tables : ##MYSQL_PREFIX## est remplacé automatiquement
---#####
---##### 			Feature(s) :
---#####				- Option pour cacher les flux souhaités sur la page d'accueil
---#####
---######################################################################################################
-
--- Mise à jour table FOLDER (Obligatoire)
-ALTER TABLE `##MYSQL_PREFIX##feed` DROP `isverbose`;
-ALTER TABLE `##MYSQL_PREFIX##feed` ADD `isverbose` INT(1) NOT NULL;
-
--- évolution pour les flux RSS défini verbeux qu'il faut ou ne faut pas afficher sur la page d'accueil.
-DELETE FROM `##MYSQL_PREFIX##configuration` WHERE `key` = 'optionFeedIsVerbose';
-INSERT INTO `##MYSQL_PREFIX##configuration` (`key`,`value`) VALUES ('optionFeedIsVerbose',1);
\ No newline at end of file
diff --git a/leed/updates/00002-feedState-20140227.sql b/leed/updates/00002-feedState-20140227.sql
deleted file mode 100644
index 9f7f8136011caa056fc30743322a44f3037a3459..0000000000000000000000000000000000000000
--- a/leed/updates/00002-feedState-20140227.sql
+++ /dev/null
@@ -1,16 +0,0 @@
---######################################################################################################
---#####
---#####     MISE À JOUR Base de données de Leed
---#####			Date : 27/02/2014
---#####			Version Leed : v1.7
---#####
---#####				Préfixe des tables : ##MYSQL_PREFIX## est remplacé automatiquement
---#####
---##### 			Feature(s) :
---#####				- Option pour stocker si le flux à eu des erreurs lors de la dernière synchro.
---#####
---######################################################################################################
-
--- Mise à jour table FEED (Obligatoire)
-ALTER TABLE `##MYSQL_PREFIX##feed` DROP `lastSyncInError`;
-ALTER TABLE `##MYSQL_PREFIX##feed` ADD `lastSyncInError` INT(1) DEFAULT 0 NOT NULL;
diff --git a/leed/updates/00003-ContentMediumText-20140303.sql b/leed/updates/00003-ContentMediumText-20140303.sql
deleted file mode 100644
index c93640ad2b4b8b8a5d64c468b9196e8687c209bd..0000000000000000000000000000000000000000
--- a/leed/updates/00003-ContentMediumText-20140303.sql
+++ /dev/null
@@ -1,15 +0,0 @@
---######################################################################################################
---#####
---#####     MISE À JOUR Base de données de Leed
---#####			Date : 03/03/2014
---#####			Version Leed : v1.7
---#####
---#####				Préfixe des tables : ##MYSQL_PREFIX## est remplacé automatiquement
---#####
---##### 			Feature(s) :
---#####				- Augmentation de la taille du champs pour permettre l'insertion de gros articles
---#####
---######################################################################################################
-
--- Mise à jour table event (Obligatoire)
-ALTER TABLE `##MYSQL_PREFIX##event` CHANGE `content` `content` MEDIUMTEXT;
diff --git a/leed/updates/00004-articleDisplayMode-20140306.sql b/leed/updates/00004-articleDisplayMode-20140306.sql
deleted file mode 100644
index 843e18613e87a488b537d0d6748ce0960b75b693..0000000000000000000000000000000000000000
--- a/leed/updates/00004-articleDisplayMode-20140306.sql
+++ /dev/null
@@ -1,18 +0,0 @@
---######################################################################################################
---#####
---#####     MISE À JOUR Base de données de Leed
---#####			Date : 06/03/2014
---#####			Version Leed : v1.7
---#####
---#####				Préfixe des tables : ##MYSQL_PREFIX## est remplacé automatiquement
---#####
---##### 			Feature(s) :
---#####				- Pliage des articles - issues : #87
---#####
---######################################################################################################
-
--- insertion du paramétrage par défaut
-INSERT INTO `##MYSQL_PREFIX##configuration` (`key`, `value`) VALUES ('articleDisplayMode','summary');
--- suppression des anciennes variables
-DELETE FROM `##MYSQL_PREFIX##configuration` WHERE (`key` = 'articleDisplayContent');
-DELETE FROM `##MYSQL_PREFIX##configuration` WHERE (`key` = 'articleView');
\ No newline at end of file
diff --git a/leed/updates/00004-variableTheme-20140309.sql b/leed/updates/00004-variableTheme-20140309.sql
deleted file mode 100644
index b63fa9720098022cbae75338d7d5a474f926f13d..0000000000000000000000000000000000000000
--- a/leed/updates/00004-variableTheme-20140309.sql
+++ /dev/null
@@ -1,15 +0,0 @@
---######################################################################################################
---#####
---#####     MISE À JOUR Base de données de Leed
---#####			Date : 09/03/2014
---#####			Version Leed : v1.7
---#####
---##### 		Préfixe des tables : ##MYSQL_PREFIX## est remplacé automatiquement
---#####
---##### 		Feature(s) :
---#####			- Ajout de la variable 'theme' remplaçant celle de 'constant.php'
---#####
---######################################################################################################
-
--- Mise à jour table event (Obligatoire)
-INSERT INTO `##MYSQL_PREFIX##configuration` (`key`, `value`) VALUES ('theme','marigolds');
diff --git a/leed/updates/00005-variableSyncGradCount-20140309.sql b/leed/updates/00005-variableSyncGradCount-20140309.sql
deleted file mode 100644
index ed56156cd9dc1d396c48254c317638ad59f2f20b..0000000000000000000000000000000000000000
--- a/leed/updates/00005-variableSyncGradCount-20140309.sql
+++ /dev/null
@@ -1,15 +0,0 @@
---######################################################################################################
---#####
---#####     MISE À JOUR Base de données de Leed
---#####			Date : 09/03/2014
---#####			Version Leed : v1.7
---#####
---##### 		Préfixe des tables : ##MYSQL_PREFIX## est remplacé automatiquement
---#####
---##### 		Feature(s) :
---#####			- Ajout de la variable 'syncGradCount' remplaçant celle de 'constant.php'
---#####
---######################################################################################################
-
--- Mise à jour table event (Obligatoire)
-INSERT INTO `##MYSQL_PREFIX##configuration` (`key`, `value`) VALUES ('syncGradCount','10');
diff --git a/leed/updates/00006-IdxLeedEvent-20161206.sql b/leed/updates/00006-IdxLeedEvent-20161206.sql
deleted file mode 100644
index 2501d7bae0f7b9eab6828e3c3dc355e442edf727..0000000000000000000000000000000000000000
--- a/leed/updates/00006-IdxLeedEvent-20161206.sql
+++ /dev/null
@@ -1,15 +0,0 @@
---######################################################################################################
---#####
---#####     MISE À JOUR Base de données de Leed
---#####			Date : 06/12/2016
---#####			Version Leed : v1.7
---#####
---##### 		Préfixe des tables : ##MYSQL_PREFIX## est remplacé automatiquement
---#####
---##### 		Feature(s) :
---#####			- Ajout d'index pour optimiser la lecture
---#####
---######################################################################################################
-
--- Mise à jour table event
-CREATE INDEX indexguidfeed on `##MYSQL_PREFIX##event` (guid(60),feed);
diff --git a/leed/updates/00007-otp-20160107.sql b/leed/updates/00007-otp-20160107.sql
deleted file mode 100644
index 586f73396bbaa9a11c42169dc1db39a200cf6132..0000000000000000000000000000000000000000
--- a/leed/updates/00007-otp-20160107.sql
+++ /dev/null
@@ -1,15 +0,0 @@
---######################################################################################################
---#####
---#####     MISE À JOUR Base de données de Leed
---#####			Date : 07/01/2017
---#####			Version Leed : v1.7
---#####
---##### 		Préfixe des tables : ##MYSQL_PREFIX## est remplacé automatiquement
---#####
---##### 		Feature(s) :
---#####			- Champs pour le One Time Password des utilisateurs
---#####
---######################################################################################################
-
--- Mise à jour table user
-ALTER TABLE `##MYSQL_PREFIX##user` ADD `otpSecret` VARCHAR(225);
diff --git a/leed/updates/00008-unique-20160124.sql b/leed/updates/00008-unique-20160124.sql
deleted file mode 100644
index eed11aca2542936721bf767f6e9d68cd5cccd795..0000000000000000000000000000000000000000
--- a/leed/updates/00008-unique-20160124.sql
+++ /dev/null
@@ -1,24 +0,0 @@
---######################################################################################################
---#####
---#####     MISE À JOUR Base de données de Leed
---#####			Date : 24/01/2017
---#####			Version Leed : v1.7
---#####
---##### 		Feature(s) :
---#####			- Rend unique le login d'un utilisateur
---#####			- Le champ `key` des configurations est maintenant un varchar 255
---#####			- Rend unique la colonne `key` des paramètres de configuration
---#####
---######################################################################################################
-
--- Mise à jour table user
-ALTER TABLE `##MYSQL_PREFIX##user` ADD CONSTRAINT `uniquelogin` UNIQUE (login);
-
-ALTER TABLE `##MYSQL_PREFIX##configuration` MODIFY `key` VARCHAR(255) NOT NULL;
-CREATE TABLE `##MYSQL_PREFIX##configuration_new` LIKE `##MYSQL_PREFIX##configuration`;
-ALTER TABLE `##MYSQL_PREFIX##configuration_new` ADD UNIQUE `uniquekey` (`key`);
-INSERT INTO `##MYSQL_PREFIX##configuration_new`
-    SELECT * FROM `##MYSQL_PREFIX##configuration`
-        GROUP BY (`key`);
-RENAME TABLE `##MYSQL_PREFIX##configuration` TO `##MYSQL_PREFIX##configuration_old`, `##MYSQL_PREFIX##configuration_new` to `##MYSQL_PREFIX##configuration`;
--- DROP TABLE `##MYSQL_PREFIX##configuration_old`;
diff --git a/leed/updates/00009-db-convert-to-utf8mb4.sql b/leed/updates/00009-db-convert-to-utf8mb4.sql
deleted file mode 100644
index ebb571ada9ffb87ec00fe7db462cc0ce6cecf277..0000000000000000000000000000000000000000
--- a/leed/updates/00009-db-convert-to-utf8mb4.sql
+++ /dev/null
@@ -1,36 +0,0 @@
---######################################################################################################
---#####
---#####     MISE À JOUR Base de données de Leed
---#####			Date : 18/01/2020
---#####			Version Leed : v1.8.5
---#####
---##### 		Feature(s) :
---#####			- Converti les tables vers l'encodage utf8mb4 pour gérer une palette de caractères bien plus grande
---#####
---######################################################################################################
-
-ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;
---# For each table:
-ALTER TABLE `##MYSQL_PREFIX##configuration` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-ALTER TABLE `##MYSQL_PREFIX##event` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-ALTER TABLE `##MYSQL_PREFIX##feed` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-ALTER TABLE `##MYSQL_PREFIX##folder` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-ALTER TABLE `##MYSQL_PREFIX##user` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
---# For each column:
-ALTER TABLE `##MYSQL_PREFIX##configuration` CHANGE `key` `key` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##configuration` CHANGE `value` `value` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##event` CHANGE `title` `title` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##event` CHANGE `creator` `creator` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##event` CHANGE `guid` `guid` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##event` CHANGE `content` `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##event` CHANGE `description` `description` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##event` CHANGE `link` `link` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##feed` CHANGE `name` `name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##feed` CHANGE `lastupdate` `lastupdate` VARCHAR(225) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##feed` CHANGE `description` `description` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##feed` CHANGE `website` `website` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##feed` CHANGE `url` `url` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##folder` CHANGE `name` `name` VARCHAR(225) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##user` CHANGE `login` `login` VARCHAR(225) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##user` CHANGE `password` `password` VARCHAR(225) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
-ALTER TABLE `##MYSQL_PREFIX##user` CHANGE `otpSecret` `otpSecret` VARCHAR(225) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;