-
\ No newline at end of file
+
diff --git a/ext/admin/attendance/index.php b/ext/admin/attendance/index.php
index 4301f9c0..591c4ef5 100644
--- a/ext/admin/attendance/index.php
+++ b/ext/admin/attendance/index.php
@@ -28,11 +28,8 @@ include APP_BASE_PATH.'modulejslibs.inc.php';
?>
@@ -93,4 +93,4 @@ modJsList['tabCompanyGraph'] = new CompanyGraphAdapter('CompanyStructure');
var modJs = modJsList['tabCompanyStructure'];
-
\ No newline at end of file
+
diff --git a/ext/admin/company_structure/lib.js b/ext/admin/company_structure/lib.js
index f5f81126..34d97f94 100644
--- a/ext/admin/company_structure/lib.js
+++ b/ext/admin/company_structure/lib.js
@@ -43,7 +43,8 @@ CompanyStructureAdapter.method('getFormFields', function() {
[ "type", {"label":"Type","type":"select","source":[["Company","Company"],["Head Office","Head Office"],["Regional Office","Regional Office"],["Department","Department"],["Unit","Unit"],["Sub Unit","Sub Unit"],["Other","Other"]]}],
[ "country", {"label":"Country","type":"select2","remote-source":["Country","code","name"]}],
[ "timezone", {"label":"Time Zone","type":"select2","allow-null":false,"remote-source":["Timezone","name","details"]}],
- [ "parent", {"label":"Parent Structure","type":"select","allow-null":true,"remote-source":["CompanyStructure","id","title"]}]
+ [ "parent", {"label":"Parent Structure","type":"select","allow-null":true,"remote-source":["CompanyStructure","id","title"]}],
+ [ "heads", {"label":"Heads","type":"select2multi","allow-null":true,"remote-source":["Employee","id","first_name+last_name"]}]
];
});
diff --git a/ext/admin/employees/api/EmployeesActionManager.php b/ext/admin/employees/api/EmployeesActionManager.php
index 2a518cf2..5d006cc7 100644
--- a/ext/admin/employees/api/EmployeesActionManager.php
+++ b/ext/admin/employees/api/EmployeesActionManager.php
@@ -35,7 +35,7 @@ class EmployeesActionManager extends SubActionManager{
$ok = $employee->Save();
if(!$ok){
- return new IceResponse(IceResponse::ERROR, "Error occured while activating employee");
+ return new IceResponse(IceResponse::ERROR, "Error occurred while activating employee");
}
return new IceResponse(IceResponse::SUCCESS, $employee);
@@ -161,4 +161,4 @@ class EmployeesActionManager extends SubActionManager{
}
return $data;
}
-}
\ No newline at end of file
+}
diff --git a/ext/admin/employees/api/EmployeesAdminManager.php b/ext/admin/employees/api/EmployeesAdminManager.php
index b7fd7f9a..7305a2c8 100644
--- a/ext/admin/employees/api/EmployeesAdminManager.php
+++ b/ext/admin/employees/api/EmployeesAdminManager.php
@@ -30,6 +30,7 @@ if (!class_exists('EmployeesAdminManager')) {
public function setupModuleClassDefinitions(){
$this->addModelClass('Employee');
$this->addModelClass('EmploymentStatus');
+ $this->addModelClass('EmployeeApproval');
}
public function getDashboardItemData(){
@@ -288,6 +289,25 @@ if (!class_exists('EmploymentStatus')) {
}
}
+if (!class_exists('EmployeeApproval')) {
+ class EmployeeApproval extends ICEHRM_Record {
+
+ var $_table = 'EmployeeApprovals';
+
+ public function getAdminAccess(){
+ return array("get","element","save","delete");
+ }
+
+ public function getManagerAccess(){
+ return array("get","element","save");
+ }
+
+ public function getUserAccess(){
+ return array();
+ }
+ }
+}
+
if (!class_exists('EmployeeRestEndPoint')) {
class EmployeeRestEndPoint extends RestEndPoint{
diff --git a/ext/admin/employees/customTemplates/myDetails.html b/ext/admin/employees/customTemplates/myDetails.html
index d0f87640..f26802b4 100644
--- a/ext/admin/employees/customTemplates/myDetails.html
+++ b/ext/admin/employees/customTemplates/myDetails.html
@@ -56,8 +56,7 @@
Personal Information
-
-
+
@@ -74,10 +73,7 @@
-
-
-
-
+
@@ -90,16 +86,14 @@
-
-
+
-
+
-
Contact Information
-
-
+
Contact Information
+
@@ -116,9 +110,6 @@
-
-
-
@@ -135,16 +126,14 @@
-
-
-
+
+
-
+
-
Job Details
-
-
+
Job Details
+
@@ -161,56 +150,57 @@
-
-
-
-
-
-
+
+
-
-
+
+
+
+
+
+
+
-
-
-
-
-
Change User Password
-
-
-
@@ -245,4 +235,4 @@
-
\ No newline at end of file
+
diff --git a/ext/admin/employees/dashboard.html b/ext/admin/employees/dashboard.html
index 74c34b49..2c67daed 100644
--- a/ext/admin/employees/dashboard.html
+++ b/ext/admin/employees/dashboard.html
@@ -3,17 +3,17 @@
- Employee needs a User to login to IceHrm. Do you want to create a user for this employee now?
You can do this later through Users module if required.
+ =LanguageManager::tran('Employee needs a User to login to IceHrm. Do you want to create a user for this employee now?')?>
=LanguageManager::tran('You can do this later through Users module if required.')?>
-
\ No newline at end of file
+
diff --git a/ext/admin/employees/lib.js b/ext/admin/employees/lib.js
index 42c729c7..3a266173 100644
--- a/ext/admin/employees/lib.js
+++ b/ext/admin/employees/lib.js
@@ -36,7 +36,7 @@ EmployeeAdapter.method('setFieldNameMap', function(fields) {
if(field.display == "Hidden"){
this.hiddenFields[field.name] = field;
}else{
- if(field.display == "Table and Form"){
+ if(field.display == "Table and Form" || field.display == "Form"){
this.tableFields[field.name] = field;
}else{
this.formOnlyFields[field.name] = field;
diff --git a/ext/admin/fieldnames/api/FieldnamesAdminManager.php b/ext/admin/fieldnames/api/FieldnamesAdminManager.php
index 26273e7c..24c5a159 100644
--- a/ext/admin/fieldnames/api/FieldnamesAdminManager.php
+++ b/ext/admin/fieldnames/api/FieldnamesAdminManager.php
@@ -53,5 +53,30 @@ if (!class_exists('CustomField')) {
public function getAnonymousAccess(){
return array("get","element");
}
+
+ public function validateSave($obj){
+ $type = $obj->type;
+ $baseObject = new $type();
+ $fields = $baseObject->getObjectKeys();
+ if(isset($fields[$obj->name])){
+ return new IceResponse(IceResponse::ERROR,"Column name already exists by default");
+ }
+
+ $cf = new CustomField();
+ if(empty($obj->id)){
+ $cf->Load("type = ? and name = ?",array($obj->type, $obj->name));
+ if($cf->name == $obj->name){
+ return new IceResponse(IceResponse::ERROR,"Another custom field with same name has already been added");
+ }
+ }else{
+ $cf->Load("type = ? and name = ? and id <> ?",array($obj->type, $obj->name, $obj->id));
+ if($cf->name == $obj->name){
+ return new IceResponse(IceResponse::ERROR,"Another custom field with same name has already been added");
+ }
+ }
+
+ return new IceResponse(IceResponse::SUCCESS,"");
+ }
+
}
-}
\ No newline at end of file
+}
diff --git a/ext/admin/fieldnames/index.php b/ext/admin/fieldnames/index.php
index ecd856e5..700571f3 100644
--- a/ext/admin/fieldnames/index.php
+++ b/ext/admin/fieldnames/index.php
@@ -15,13 +15,8 @@ include APP_BASE_PATH.'modulejslibs.inc.php';
?>
@@ -71,4 +70,4 @@ modJsList['tabEmploymentStatus'] = new EmploymentStatusAdapter('EmploymentStatus
var modJs = modJsList['tabJobTitles'];
-
\ No newline at end of file
+
diff --git a/ext/admin/loans/index.php b/ext/admin/loans/index.php
index c00e9b7c..f61a6548 100644
--- a/ext/admin/loans/index.php
+++ b/ext/admin/loans/index.php
@@ -28,8 +28,8 @@ include APP_BASE_PATH.'modulejslibs.inc.php';
?>
';
+
+
+ html = html.replace('_logs_',viewLogsButton);
+
+
+ if(data[this.getStatusFieldPosition()] == 'Processing'){
+ html = html.replace('_status_',statusChangeButton);
+
+ }else{
+ html = html.replace('_status_','');
+ }
+
+ html = html.replace(/_id_/g,id);
+ html = html.replace(/_BASE_/g,this.baseUrl);
+ html = html.replace(/_cstatus_/g,data[this.getStatusFieldPosition()]);
+ return html;
+});
+
+ApproveApproverAdapter.method('getStatusOptionsData', function(currentStatus) {
+ var data = {};
+ if(currentStatus != 'Processing'){
+
+ }else{
+ data["Approved"] = "Approved";
+ data["Rejected"] = "Rejected";
+
+ }
+
+ return data;
+});
+
+ApproveApproverAdapter.method('getStatusOptions', function(currentStatus) {
+ return this.generateOptions(this.getStatusOptionsData(currentStatus));
+});
+
+
/**
diff --git a/src/api/Base.js b/src/api/Base.js
index 34b803d0..c0b10a9a 100644
--- a/src/api/Base.js
+++ b/src/api/Base.js
@@ -1,23 +1,23 @@
/*
- This file is part of Ice Framework.
+This file is part of Ice Framework.
- Ice Framework is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+Ice Framework is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
- Ice Framework 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 General Public License for more details.
+Ice Framework 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 General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Ice Framework. If not, see .
+You should have received a copy of the GNU General Public License
+along with Ice Framework. If not, see .
- ------------------------------------------------------------------
+------------------------------------------------------------------
- Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
- Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
+Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
+Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
*/
@@ -38,8 +38,9 @@ function IceHRMBase() {
this.showFormOnPopup = false;
this.filtersAlreadySet = false;
this.currentFilterString = "";
- this.sorting = 0;
+ this.sorting = 0;
this.settings = {};
+ this.translations = {};
}
this.fieldTemplates = null;
@@ -51,6 +52,7 @@ this.fieldMasterDataKeys = null;
this.fieldMasterDataCallback = null;
this.sourceMapping = null;
this.currentId = null;
+this.currentElement = null;
this.user = null;
this.currentProfile = null;
this.permissions = {};
@@ -60,7 +62,7 @@ this.permissions = {};
this.baseUrl = null;
IceHRMBase.method('init' , function(appName, currentView, dataUrl, permissions) {
-
+
});
/**
@@ -116,6 +118,42 @@ IceHRMBase.method('setGoogleAnalytics' , function(ga) {
this.ga = ga;
});
+IceHRMBase.method('scrollToTop' , function() {
+ $("html, body").animate({ scrollTop: 0 }, "fast");
+});
+
+
+IceHRMBase.method('setTranslations' , function(txt) {
+ this.translations = txt['messages'][''];
+});
+
+IceHRMBase.method('gt' , function(key) {
+ if(this.translations[key] == undefined){
+ return key;
+ }
+ return this.translations[key][0];
+});
+
+IceHRMBase.method('addToLangTerms' , function(key) {
+ var termsArr;
+ var terms = localStorage.getItem("terms");
+ if(terms == undefined){
+ termsArr = {};
+ }else{
+ try{
+ termsArr = JSON.parse(terms);
+ }catch(e){
+ termsArr = {};
+ }
+
+ }
+
+ if(this.translations[key] == undefined){
+ termsArr[key] = key;
+ localStorage.setItem("terms", JSON.stringify(termsArr));
+ }
+});
+
/**
* If this method returned false the action buttons in data table for modules will not be displayed.
* Override this method in module lib.js to hide action buttons
@@ -140,10 +178,10 @@ IceHRMBase.method('trackEvent' , function(action, label, value) {
this.ga.push(['_trackEvent', this.instanceId, action, label, value]);
}
}catch(e){
-
+
}
-
-
+
+
});
@@ -188,7 +226,7 @@ IceHRMBase.method('initFieldMasterData' , function(callback, loadAllCallback, lo
this.sourceMapping = {};
var fields = this.getFormFields();
var filterFields = this.getFilters();
-
+
if(filterFields != null){
for(var j=0;j';
+ html = '';
}
-
+
if(this.getFilters() != null){
if(html != ""){
html += " ";
}
- html+='';
+ html+='';
html += " ";
if(this.filtersAlreadySet){
html+='';
}else{
html+='';
}
-
+
}
-
+
html = html.replace(/__id__/g, this.getTableName());
-
+
if(this.currentFilterString != "" && this.currentFilterString != null){
html = html.replace(/__filterString__/g, this.currentFilterString);
}else{
html = html.replace(/__filterString__/g, 'Reset Filters');
}
-
+
if(html != ""){
html = '
').parent().html();
this.showDomElement("Edit",$tempDomObj,null,null,true);
@@ -1113,23 +1166,23 @@ IceHRMBase.method('showFilters', function(object) {
e.stopPropagation();
try{
modJs.filterQuery();
-
+
}catch(e){
};
return false;
});
-
+
if(this.filter != undefined && this.filter != null){
this.fillForm(this.filter,"#"+this.getTableName()+"_filter", this.getFilters());
}
-
+
});
/**
* Override this method in your module class to make changes to data fo the form before showing the form
* @method preRenderForm
- * @param object {Array} keys value list for populating form
+ * @param object {Array} keys value list for populating form
*/
IceHRMBase.method('preRenderForm', function(object) {
@@ -1139,23 +1192,23 @@ IceHRMBase.method('preRenderForm', function(object) {
/**
* Create the form
* @method renderForm
- * @param object {Array} keys value list for populating form
+ * @param object {Array} keys value list for populating form
*/
IceHRMBase.method('renderForm', function(object) {
-
+
var that = this;
- var signatureIds = [];
+ var signatureIds = [];
if(object == null || object == undefined){
this.currentId = null;
}
-
+
this.preRenderForm(object);
-
+
var formHtml = this.templates['formTemplate'];
var html = "";
var fields = this.getFormFields();
-
+
for(var i=0;i
';
+ }
+ $lines[] = $prefix.' ';
+ $lines[] = $prefix.'';
+
+ return implode("\n", $lines);
+ }
+ /**
+ * @see Exporter::getDescription
+ */
+ public static function getDescription()
+ {
+ return 'Build a HTML table';
+ }
+}
diff --git a/src/composer/vendor/gettext/languages/src/Exporter/Json.php b/src/composer/vendor/gettext/languages/src/Exporter/Json.php
new file mode 100644
index 00000000..09e79f01
--- /dev/null
+++ b/src/composer/vendor/gettext/languages/src/Exporter/Json.php
@@ -0,0 +1,63 @@
+name;
+ if (isset($language->supersededBy)) {
+ $item['supersededBy'] = $language->supersededBy;
+ }
+ if (isset($language->script)) {
+ $item['script'] = $language->script;
+ }
+ if (isset($language->territory)) {
+ $item['territory'] = $language->territory;
+ }
+ if (isset($language->baseLanguage)) {
+ $item['baseLanguage'] = $language->baseLanguage;
+ }
+ $item['formula'] = $language->formula;
+ $item['plurals'] = count($language->categories);
+ $item['cases'] = array();
+ $item['examples'] = array();
+ foreach ($language->categories as $category) {
+ $item['cases'][] = $category->id;
+ $item['examples'][$category->id] = $category->examples;
+ }
+ $list[$language->id] = $item;
+ }
+
+ return json_encode($list, static::getEncodeOptions());
+ }
+ /**
+ * @see Exporter::getDescription
+ */
+ public static function getDescription()
+ {
+ return 'Build a compressed JSON-encoded file';
+ }
+}
diff --git a/src/composer/vendor/gettext/languages/src/Exporter/Php.php b/src/composer/vendor/gettext/languages/src/Exporter/Php.php
new file mode 100644
index 00000000..d8ef4cc1
--- /dev/null
+++ b/src/composer/vendor/gettext/languages/src/Exporter/Php.php
@@ -0,0 +1,55 @@
+id.'\' => array(';
+ $lines[] = ' \'name\' => \''.addslashes($lc->name).'\',';
+ if (isset($lc->supersededBy)) {
+ $lines[] = ' \'supersededBy\' => \''.$lc->supersededBy.'\',';
+ }
+ if (isset($lc->script)) {
+ $lines[] = ' \'script\' => \''.addslashes($lc->script).'\',';
+ }
+ if (isset($lc->territory)) {
+ $lines[] = ' \'territory\' => \''.addslashes($lc->territory).'\',';
+ }
+ if (isset($lc->baseLanguage)) {
+ $lines[] = ' \'baseLanguage\' => \''.addslashes($lc->baseLanguage).'\',';
+ }
+ $lines[] = ' \'formula\' => \''.$lc->formula.'\',';
+ $lines[] = ' \'plurals\' => '.count($lc->categories).',';
+ $catNames = array();
+ foreach ($lc->categories as $c) {
+ $catNames[] = "'{$c->id}'";
+ }
+ $lines[] = ' \'cases\' => array('.implode(', ', $catNames).'),';
+ $lines[] = ' \'examples\' => array(';
+ foreach ($lc->categories as $c) {
+ $lines[] = ' \''.$c->id.'\' => \''.$c->examples.'\',';
+ }
+ $lines[] = ' ),';
+ $lines[] = ' ),';
+ }
+ $lines[] = ');';
+ $lines[] = '';
+
+ return implode("\n", $lines);
+ }
+ /**
+ * @see Exporter::getDescription
+ */
+ public static function getDescription()
+ {
+ return 'Build a PHP array';
+ }
+}
diff --git a/src/composer/vendor/gettext/languages/src/Exporter/Po.php b/src/composer/vendor/gettext/languages/src/Exporter/Po.php
new file mode 100644
index 00000000..c89ab13b
--- /dev/null
+++ b/src/composer/vendor/gettext/languages/src/Exporter/Po.php
@@ -0,0 +1,31 @@
+id.'\n"';
+ $lines[] = '"Plural-Forms: nplurals='.count($language->categories).'; plural='.$language->formula.'\n"';
+ $lines[] = '';
+
+ return implode("\n", $lines);
+ }
+ /**
+ * @see Exporter::getDescription
+ */
+ public static function getDescription()
+ {
+ return 'Build a string to be used for gettext .po files';
+ }
+}
diff --git a/src/composer/vendor/gettext/languages/src/Exporter/Prettyjson.php b/src/composer/vendor/gettext/languages/src/Exporter/Prettyjson.php
new file mode 100644
index 00000000..aa8fd991
--- /dev/null
+++ b/src/composer/vendor/gettext/languages/src/Exporter/Prettyjson.php
@@ -0,0 +1,25 @@
+loadXML('');
+ $xLanguages = $xml->firstChild;
+ foreach ($languages as $language) {
+ $xLanguage = $xml->createElement('language');
+ $xLanguage->setAttribute('id', $language->id);
+ $xLanguage->setAttribute('name', $language->name);
+ if (isset($language->supersededBy)) {
+ $xLanguage->setAttribute('supersededBy', $language->supersededBy);
+ }
+ if (isset($language->script)) {
+ $xLanguage->setAttribute('script', $language->script);
+ }
+ if (isset($language->territory)) {
+ $xLanguage->setAttribute('territory', $language->territory);
+ }
+ if (isset($language->baseLanguage)) {
+ $xLanguage->setAttribute('baseLanguage', $language->baseLanguage);
+ }
+ $xLanguage->setAttribute('formula', $language->formula);
+ foreach ($language->categories as $category) {
+ $xCategory = $xml->createElement('category');
+ $xCategory->setAttribute('id', $category->id);
+ $xCategory->setAttribute('examples', $category->examples);
+ $xLanguage->appendChild($xCategory);
+ }
+ $xLanguages->appendChild($xLanguage);
+ }
+ $xml->formatOutput = true;
+
+ return $xml->saveXML();
+ }
+ /**
+ * @see Exporter::getDescription
+ */
+ public static function getDescription()
+ {
+ return 'Build an XML file - schema available at http://mlocati.github.io/cldr-to-gettext-plural-rules/GettextLanguages.xsd';
+ }
+}
diff --git a/src/composer/vendor/gettext/languages/src/FormulaConverter.php b/src/composer/vendor/gettext/languages/src/FormulaConverter.php
new file mode 100644
index 00000000..27960903
--- /dev/null
+++ b/src/composer/vendor/gettext/languages/src/FormulaConverter.php
@@ -0,0 +1,154 @@
+ the whole 'and' group is always false
+ $gettextFormulaChunk = false;
+ break;
+ } elseif ($gettextAtom !== true) {
+ $andSeparatedChunks[] = $gettextAtom;
+ }
+ }
+ if (!isset($gettextFormulaChunk)) {
+ if (empty($andSeparatedChunks)) {
+ // All the atoms joined by 'and' always evaluate to true => the whole 'and' group is always true
+ $gettextFormulaChunk = true;
+ } else {
+ $gettextFormulaChunk = implode(' && ', $andSeparatedChunks);
+ // Special cases simplification
+ switch ($gettextFormulaChunk) {
+ case 'n >= 0 && n <= 2 && n != 2':
+ $gettextFormulaChunk = 'n == 0 || n == 1';
+ break;
+ }
+ }
+ }
+ if ($gettextFormulaChunk === true) {
+ // One part of the formula joined with the others by 'or' always evaluates to true => the whole formula always evaluates to true
+ return true;
+ } elseif ($gettextFormulaChunk !== false) {
+ $orSeparatedChunks[] = $gettextFormulaChunk;
+ }
+ }
+ if (empty($orSeparatedChunks)) {
+ // All the parts joined by 'or' always evaluate to false => the whole formula always evaluates to false
+ return false;
+ } else {
+ return implode(' || ', $orSeparatedChunks);
+ }
+ }
+ /**
+ * Converts an atomic part of the CLDR formula to its gettext representation.
+ * @param string $cldrAtom The CLDR formula atom to convert.
+ * @throws Exception
+ * @return bool|string Returns true if the gettext will always evaluate to true, false if gettext will always evaluate to false, return the gettext formula otherwise.
+ */
+ private static function convertAtom($cldrAtom)
+ {
+ $m = null;
+ $gettextAtom = $cldrAtom;
+ $gettextAtom = str_replace(' = ', ' == ', $gettextAtom);
+ $gettextAtom = str_replace('i', 'n', $gettextAtom);
+ if (preg_match('/^n( % \d+)? (!=|==) \d+$/', $gettextAtom)) {
+ return $gettextAtom;
+ }
+ if (preg_match('/^n( % \d+)? (!=|==) \d+(,\d+|\.\.\d+)+$/', $gettextAtom)) {
+ return self::expandAtom($gettextAtom);
+ }
+ if (preg_match('/^(?:v|w)(?: % 10+)? == (\d+)(?:\.\.\d+)?$/', $gettextAtom, $m)) { // For gettext: v == 0, w == 0
+ return (intval($m[1]) === 0) ? true : false;
+ }
+ if (preg_match('/^(?:v|w)(?: % 10+)? != (\d+)(?:\.\.\d+)?$/', $gettextAtom, $m)) { // For gettext: v == 0, w == 0
+ return (intval($m[1]) === 0) ? false : true;
+ }
+ if (preg_match('/^(?:f|t)(?: % 10+)? == (\d+)(?:\.\.\d+)?$/', $gettextAtom, $m)) { // f == empty, t == empty
+ return (intval($m[1]) === 0) ? true : false;
+ }
+ if (preg_match('/^(?:f|t)(?: % 10+)? != (\d+)(?:\.\.\d+)?$/', $gettextAtom, $m)) { // f == empty, t == empty
+ return (intval($m[1]) === 0) ? false : true;
+ }
+ throw new Exception("Unable to convert the formula chunk '$cldrAtom' from CLDR to gettext");
+ }
+ /**
+ * Expands an atom containing a range (for instance: 'n == 1,3..5').
+ * @param string $atom
+ * @throws Exception
+ * @return string
+ */
+ private static function expandAtom($atom)
+ {
+ $m = null;
+ if (preg_match('/^(n(?: % \d+)?) (==|!=) (\d+(?:\.\.\d+|,\d+)+)$/', $atom, $m)) {
+ $what = $m[1];
+ $op = $m[2];
+ $chunks = array();
+ foreach (explode(',', $m[3]) as $range) {
+ $chunk = null;
+ if ((!isset($chunk)) && preg_match('/^\d+$/', $range)) {
+ $chunk = "$what $op $range";
+ }
+ if ((!isset($chunk)) && preg_match('/^(\d+)\.\.(\d+)$/', $range, $m)) {
+ $from = intval($m[1]);
+ $to = intval($m[2]);
+ if (($to - $from) === 1) {
+ switch ($op) {
+ case '==':
+ $chunk = "($what == $from || $what == $to)";
+ break;
+ case '!=':
+ $chunk = "$what != $from && $what == $to";
+ break;
+ }
+ } else {
+ switch ($op) {
+ case '==':
+ $chunk = "$what >= $from && $what <= $to";
+ break;
+ case '!=':
+ $chunk = "($what < $from || $what > $to)";
+ break;
+ }
+ }
+ }
+ if (!isset($chunk)) {
+ throw new Exception("Unhandled range '$range' in '$atom'");
+ }
+ $chunks[] = $chunk;
+ }
+ if (count($chunks) === 1) {
+ return $chunks[0];
+ }
+ switch ($op) {
+ case '==':
+ return '('.implode(' || ', $chunks).')';break;
+ case '!=':
+ return implode(' && ', $chunks);
+ }
+ }
+ throw new Exception("Unable to expand '$atom'");
+ }
+}
diff --git a/src/composer/vendor/gettext/languages/src/Language.php b/src/composer/vendor/gettext/languages/src/Language.php
new file mode 100644
index 00000000..898bb61e
--- /dev/null
+++ b/src/composer/vendor/gettext/languages/src/Language.php
@@ -0,0 +1,366 @@
+id = $info['id'];
+ $this->name = $info['name'];
+ $this->supersededBy = isset($info['supersededBy']) ? $info['supersededBy'] : null;
+ $this->script = isset($info['script']) ? $info['script'] : null;
+ $this->territory = isset($info['territory']) ? $info['territory'] : null;
+ $this->baseLanguage = isset($info['baseLanguage']) ? $info['baseLanguage'] : null;
+ // Let's build the category list
+ $this->categories = array();
+ foreach ($info['categories'] as $cldrCategoryId => $cldrFormulaAndExamples) {
+ $category = new Category($cldrCategoryId, $cldrFormulaAndExamples);
+ foreach ($this->categories as $c) {
+ if ($category->id === $c->id) {
+ throw new Exception("The category '{$category->id}' is specified more than once");
+ }
+ }
+ $this->categories[] = $category;
+ }
+ if (empty($this->categories)) {
+ throw new Exception("The language '$id' does not have any plural category");
+ }
+ // Let's sort the categories from 'zero' to 'other'
+ usort($this->categories, function (Category $category1, Category $category2) {
+ return array_search($category1->id, CldrData::$categories) - array_search($category2->id, CldrData::$categories);
+ });
+ // The 'other' category should always be there
+ if ($this->categories[count($this->categories) - 1]->id !== CldrData::OTHER_CATEGORY) {
+ throw new Exception("The language '$id' does not have the '".CldrData::OTHER_CATEGORY."' plural category");
+ }
+ $this->checkAlwaysTrueCategories();
+ $this->checkAlwaysFalseCategories();
+ $this->checkAllCategoriesWithExamples();
+ $this->formula = $this->buildFormula();
+ }
+ /**
+ * Return a list of all languages available.
+ * @throws Exception
+ * @return Language[]
+ */
+ public static function getAll()
+ {
+ $result = array();
+ foreach (array_keys(CldrData::getLanguageNames()) as $cldrLanguageId) {
+ $result[] = new Language(CldrData::getLanguageInfo($cldrLanguageId));
+ }
+
+ return $result;
+ }
+ /**
+ * Return a Language instance given the language id
+ * @param string $id
+ * @return Language|null
+ */
+ public static function getById($id)
+ {
+ $result = null;
+ $info = CldrData::getLanguageInfo($id);
+ if (isset($info)) {
+ $result = new Language($info);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Let's look for categories that will always occur.
+ * This because with decimals (CLDR) we may have more cases, with integers (gettext) we have just one case.
+ * If we found that (single) category we reduce the categories to that one only.
+ */
+ private function checkAlwaysTrueCategories()
+ {
+ $alwaysTrueCategory = null;
+ foreach ($this->categories as $category) {
+ if ($category->formula === true) {
+ if (!isset($category->examples)) {
+ throw new Exception("The category '{$category->id}' should always occur, but it does not have examples (so for CLDR it will never occur for integers!)");
+ }
+ $alwaysTrueCategory = $category;
+ break;
+ }
+ }
+ if (isset($alwaysTrueCategory)) {
+ foreach ($this->categories as $category) {
+ if (($category !== $alwaysTrueCategory) && isset($category->examples)) {
+ throw new Exception("The category '{$category->id}' should never occur, but it has some examples (so for CLDR it will occur!)");
+ }
+ }
+ $alwaysTrueCategory->id = CldrData::OTHER_CATEGORY;
+ $alwaysTrueCategory->formula = null;
+ $this->categories = array($alwaysTrueCategory);
+ }
+ }
+ /**
+ * Let's look for categories that will never occur.
+ * This because with decimals (CLDR) we may have more cases, with integers (gettext) we have some less cases.
+ * If we found those categories we strip them out.
+ */
+ private function checkAlwaysFalseCategories()
+ {
+ $filtered = array();
+ foreach ($this->categories as $category) {
+ if ($category->formula === false) {
+ if (isset($category->examples)) {
+ throw new Exception("The category '{$category->id}' should never occur, but it has examples (so for CLDR it may occur!)");
+ }
+ } else {
+ $filtered[] = $category;
+ }
+ }
+ $this->categories = $filtered;
+ }
+ /**
+ * Let's look for categories that don't have examples.
+ * This because with decimals (CLDR) we may have more cases, with integers (gettext) we have some less cases.
+ * If we found those categories, we check that they never occur and we strip them out.
+ * @throws Exception
+ */
+ private function checkAllCategoriesWithExamples()
+ {
+ $allCategoriesIds = array();
+ $goodCategories = array();
+ $badCategories = array();
+ $badCategoriesIds = array();
+ foreach ($this->categories as $category) {
+ $allCategoriesIds[] = $category->id;
+ if (isset($category->examples)) {
+ $goodCategories[] = $category;
+ } else {
+ $badCategories[] = $category;
+ $badCategoriesIds[] = $category->id;
+ }
+ }
+ if (empty($badCategories)) {
+ return;
+ }
+ $removeCategoriesWithoutExamples = false;
+ switch (implode(',', $badCategoriesIds).'@'.implode(',', $allCategoriesIds)) {
+ case CldrData::OTHER_CATEGORY.'@one,few,many,'.CldrData::OTHER_CATEGORY:
+ switch ($this->buildFormula()) {
+ case '(n % 10 == 1 && n % 100 != 11) ? 0 : ((n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) ? 1 : ((n % 10 == 0 || n % 10 >= 5 && n % 10 <= 9 || n % 100 >= 11 && n % 100 <= 14) ? 2 : 3))':
+ // Numbers ending with 0 => case 2 ('many')
+ // Numbers ending with 1 but not with 11 => case 0 ('one')
+ // Numbers ending with 11 => case 2 ('many')
+ // Numbers ending with 2 but not with 12 => case 1 ('few')
+ // Numbers ending with 12 => case 2 ('many')
+ // Numbers ending with 3 but not with 13 => case 1 ('few')
+ // Numbers ending with 13 => case 2 ('many')
+ // Numbers ending with 4 but not with 14 => case 1 ('few')
+ // Numbers ending with 14 => case 2 ('many')
+ // Numbers ending with 5 => case 2 ('many')
+ // Numbers ending with 6 => case 2 ('many')
+ // Numbers ending with 7 => case 2 ('many')
+ // Numbers ending with 8 => case 2 ('many')
+ // Numbers ending with 9 => case 2 ('many')
+ // => the 'other' case never occurs: use 'other' for 'many'
+ $removeCategoriesWithoutExamples = true;
+ break;
+ case '(n == 1) ? 0 : ((n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) ? 1 : ((n != 1 && (n % 10 == 0 || n % 10 == 1) || n % 10 >= 5 && n % 10 <= 9 || n % 100 >= 12 && n % 100 <= 14) ? 2 : 3))':
+ // Numbers ending with 0 => case 2 ('many')
+ // Numbers ending with 1 but not number 1 => case 2 ('many')
+ // Number 1 => case 0 ('one')
+ // Numbers ending with 2 but not with 12 => case 1 ('few')
+ // Numbers ending with 12 => case 2 ('many')
+ // Numbers ending with 3 but not with 13 => case 1 ('few')
+ // Numbers ending with 13 => case 2 ('many')
+ // Numbers ending with 4 but not with 14 => case 1 ('few')
+ // Numbers ending with 14 => case 2 ('many')
+ // Numbers ending with 5 => case 2 ('many')
+ // Numbers ending with 6 => case 2 ('many')
+ // Numbers ending with 7 => case 2 ('many')
+ // Numbers ending with 8 => case 2 ('many')
+ // Numbers ending with 9 => case 2 ('many')
+ // => the 'other' case never occurs: use 'other' for 'many'
+ $removeCategoriesWithoutExamples = true;
+ break;
+ }
+ }
+ if (!$removeCategoriesWithoutExamples) {
+ throw new Exception("Unhandled case of plural categories without examples '".implode(', ', $badCategoriesIds)."' out of '".implode(', ', $allCategoriesIds)."'");
+ }
+ if ($badCategories[count($badCategories) - 1]->id === CldrData::OTHER_CATEGORY) {
+ // We're removing the 'other' cagory: let's change the last good category to 'other'
+ $lastGood = $goodCategories[count($goodCategories) - 1];
+ $lastGood->id = CldrData::OTHER_CATEGORY;
+ $lastGood->formula = null;
+ }
+ $this->categories = $goodCategories;
+ }
+ /**
+ * Build the formula starting from the currently defined categories.
+ * @return string
+ */
+ private function buildFormula()
+ {
+ $numCategories = count($this->categories);
+ switch ($numCategories) {
+ case 1:
+ // Just one category
+ return '0';
+ case 2:
+ return self::reduceFormula(self::reverseFormula($this->categories[0]->formula));
+ default:
+ $formula = strval($numCategories - 1);
+ for ($i = $numCategories - 2; $i >= 0; $i--) {
+ $f = self::reduceFormula($this->categories[$i]->formula);
+ if (!preg_match('/^\([^()]+\)$/', $f)) {
+ $f = "($f)";
+ }
+ $formula = "$f ? $i : $formula";
+ if ($i > 0) {
+ $formula = "($formula)";
+ }
+ }
+
+ return $formula;
+ }
+ }
+ /**
+ * Reverse a formula.
+ * @param string $formula
+ * @throws Exception
+ * @return string
+ */
+ private static function reverseFormula($formula)
+ {
+ if (preg_match('/^n( % \d+)? == \d+(\.\.\d+|,\d+)*?$/', $formula)) {
+ return str_replace(' == ', ' != ', $formula);
+ }
+ if (preg_match('/^n( % \d+)? != \d+(\.\.\d+|,\d+)*?$/', $formula)) {
+ return str_replace(' != ', ' == ', $formula);
+ }
+ if (preg_match('/^\(?n == \d+ \|\| n == \d+\)?$/', $formula)) {
+ return trim(str_replace(array(' == ', ' || '), array(' != ', ' && '), $formula), '()');
+ }
+ $m = null;
+ if (preg_match('/^(n(?: % \d+)?) == (\d+) && (n(?: % \d+)?) != (\d+)$/', $formula, $m)) {
+ return "{$m[1]} != {$m[2]} || {$m[3]} == {$m[4]}";
+ }
+ switch ($formula) {
+ case '(n == 1 || n == 2 || n == 3) || n % 10 != 4 && n % 10 != 6 && n % 10 != 9':
+ return 'n != 1 && n != 2 && n != 3 && (n % 10 == 4 || n % 10 == 6 || n % 10 == 9)';
+ case '(n == 0 || n == 1) || n >= 11 && n <= 99':
+ return 'n >= 2 && (n < 11 || n > 99)';
+ }
+ throw new Exception("Unable to reverse the formula '$formula'");
+ }
+ /**
+ * Reduce some excessively complex formulas.
+ * @param string $formula
+ * @return string
+ */
+ private static function reduceFormula($formula)
+ {
+ $map = array(
+ 'n != 0 && n != 1' => 'n > 1' ,
+ '(n == 0 || n == 1) && n != 0' => 'n == 1',
+ );
+
+ return isset($map[$formula]) ? $map[$formula] : $formula;
+ }
+ /**
+ * Take one variable and, if it's a string, we transliterate it to US-ASCII.
+ * @param mixed $value The variable to work on.
+ * @throws Exception
+ */
+ private static function asciifier(&$value)
+ {
+ if (is_string($value) && ($value !== '')) {
+ // Avoid converting from 'Ÿ' to '"Y', let's prefer 'Y'
+ $transliterated = strtr($value, array(
+ 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A',
+ 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E',
+ 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I',
+ 'Ñ' => 'N',
+ 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O',
+ 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U',
+ 'Ÿ' => 'Y', 'Ý' => 'Y',
+ 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a',
+ 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e',
+ 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i',
+ 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o',
+ 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'u',
+ 'ý' => 'y', 'ÿ' => 'y',
+ ));
+ $transliterated = @iconv('UTF-8', 'US-ASCII//IGNORE//TRANSLIT', $transliterated);
+ if (($transliterated === false) || ($transliterated === '')) {
+ throw new Exception("Unable to transliterate '$value'");
+ }
+ $value = $transliterated;
+ }
+ }
+ /**
+ * Returns a clone of this instance with all the strings to US-ASCII.
+ * @return Language
+ */
+ public function getUSAsciiClone()
+ {
+ $clone = clone $this;
+ self::asciifier($clone->name);
+ self::asciifier($clone->formula);
+ $clone->categories = array();
+ foreach ($this->categories as $category) {
+ $categoryClone = clone $category;
+ self::asciifier($categoryClone->examples);
+ $clone->categories[] = $categoryClone;
+ }
+
+ return $clone;
+ }
+}
diff --git a/src/composer/vendor/gettext/languages/src/autoloader.php b/src/composer/vendor/gettext/languages/src/autoloader.php
new file mode 100644
index 00000000..435eb890
--- /dev/null
+++ b/src/composer/vendor/gettext/languages/src/autoloader.php
@@ -0,0 +1,12 @@
+> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`; fi
+ - if [ ${TRAVIS_PHP_VERSION:0:3} == "5.2" ]; then sed -i.bak "s|vendor/autoload.php|test/bootstrap.php|" phpunit.xml.dist; fi
+
+matrix:
+ fast_finish: true
+ exclude:
+ - php: hhvm
+ env: TWIG_EXT=yes
+ allow_failures:
+ - php: 7.0
+ env: TWIG_EXT=yes
diff --git a/src/composer/vendor/twig/twig/CHANGELOG b/src/composer/vendor/twig/twig/CHANGELOG
new file mode 100644
index 00000000..e01334f6
--- /dev/null
+++ b/src/composer/vendor/twig/twig/CHANGELOG
@@ -0,0 +1,821 @@
+* 1.23.3 (2016-01-11)
+
+ * fixed typo
+
+* 1.23.2 (2015-01-11)
+
+ * added versions in deprecated messages
+ * made file cache tolerant for trailing (back)slashes on directory configuration
+ * deprecated unused Twig_Node_Expression_ExtensionReference class
+
+* 1.23.1 (2015-11-05)
+
+ * fixed some exception messages which triggered PHP warnings
+ * fixed BC on Twig_Test_NodeTestCase
+
+* 1.23.0 (2015-10-29)
+
+ * deprecated the possibility to override an extension by registering another one with the same name
+ * deprecated Twig_ExtensionInterface::getGlobals() (added Twig_Extension_GlobalsInterface for BC)
+ * deprecated Twig_ExtensionInterface::initRuntime() (added Twig_Extension_InitRuntimeInterface for BC)
+ * deprecated Twig_Environment::computeAlternatives()
+
+* 1.22.3 (2015-10-13)
+
+ * fixed regression when using null as a cache strategy
+ * improved performance when checking template freshness
+ * fixed warnings when loaded templates do not exist
+ * fixed template class name generation to prevent possible collisions
+ * fixed logic for custom escapers to call them even on integers and null values
+ * changed template cache names to take into account the Twig C extension
+
+* 1.22.2 (2015-09-22)
+
+ * fixed a race condition in template loading
+
+* 1.22.1 (2015-09-15)
+
+ * fixed regression in template_from_string
+
+* 1.22.0 (2015-09-13)
+
+ * made Twig_Test_IntegrationTestCase more flexible
+ * added an option to force PHP bytecode invalidation when writing a compiled template into the cache
+ * fixed the profiler duration for the root node
+ * changed template cache names to take into account enabled extensions
+ * deprecated Twig_Environment::clearCacheFiles(), Twig_Environment::getCacheFilename(),
+ Twig_Environment::writeCacheFile(), and Twig_Environment::getTemplateClassPrefix()
+ * added a way to override the filesystem template cache system
+ * added a way to get the original template source from Twig_Template
+
+* 1.21.2 (2015-09-09)
+
+ * fixed variable names for the deprecation triggering code
+ * fixed escaping strategy detection based on filename
+ * added Traversable support for replace, merge, and sort
+ * deprecated support for character by character replacement for the "replace" filter
+
+* 1.21.1 (2015-08-26)
+
+ * fixed regression when using the deprecated Twig_Test_* classes
+
+* 1.21.0 (2015-08-24)
+
+ * added deprecation notices for deprecated features
+ * added a deprecation "framework" for filters/functions/tests and test fixtures
+
+* 1.20.0 (2015-08-12)
+
+ * forbid access to the Twig environment from templates and internal parts of Twig_Template
+ * fixed limited RCEs when in sandbox mode
+ * deprecated Twig_Template::getEnvironment()
+ * deprecated the _self variable for usage outside of the from and import tags
+ * added Twig_BaseNodeVisitor to ease the compatibility of node visitors
+ between 1.x and 2.x
+
+* 1.19.0 (2015-07-31)
+
+ * fixed wrong error message when including an undefined template in a child template
+ * added support for variadic filters, functions, and tests
+ * added support for extra positional arguments in macros
+ * added ignore_missing flag to the source function
+ * fixed batch filter with zero items
+ * deprecated Twig_Environment::clearTemplateCache()
+ * fixed sandbox disabling when using the include function
+
+* 1.18.2 (2015-06-06)
+
+ * fixed template/line guessing in exceptions for nested templates
+ * optimized the number of inodes and the size of realpath cache when using the cache
+
+* 1.18.1 (2015-04-19)
+
+ * fixed memory leaks in the C extension
+ * deprecated Twig_Loader_String
+ * fixed the slice filter when used with a SimpleXMLElement object
+ * fixed filesystem loader when trying to load non-files (like directories)
+
+* 1.18.0 (2015-01-25)
+
+ * fixed some error messages where the line was wrong (unknown variables or argument names)
+ * added a new way to customize the main Module node (via empty nodes)
+ * added Twig_Environment::createTemplate() to create a template from a string
+ * added a profiler
+ * fixed filesystem loader cache when different file paths are used for the same template
+
+* 1.17.0 (2015-01-14)
+
+ * added a 'filename' autoescaping strategy, which dynamically chooses the
+ autoescaping strategy for a template based on template file extension.
+
+* 1.16.3 (2014-12-25)
+
+ * fixed regression for dynamic parent templates
+ * fixed cache management with statcache
+ * fixed a regression in the slice filter
+
+* 1.16.2 (2014-10-17)
+
+ * fixed timezone on dates as strings
+ * fixed 2-words test names when a custom node class is not used
+ * fixed macros when using an argument named like a PHP super global (like GET or POST)
+ * fixed date_modify when working with DateTimeImmutable
+ * optimized for loops
+ * fixed multi-byte characters handling in the split filter
+ * fixed a regression in the in operator
+ * fixed a regression in the slice filter
+
+* 1.16.1 (2014-10-10)
+
+ * improved error reporting in a sandboxed template
+ * fixed missing error file/line information under certain circumstances
+ * fixed wrong error line number in some error messages
+ * fixed the in operator to use strict comparisons
+ * sped up the slice filter
+ * fixed for mb function overload mb_substr acting different
+ * fixed the attribute() function when passing a variable for the arguments
+
+* 1.16.0 (2014-07-05)
+
+ * changed url_encode to always encode according to RFC 3986
+ * fixed inheritance in a 'use'-hierarchy
+ * removed the __toString policy check when the sandbox is disabled
+ * fixed recursively calling blocks in templates with inheritance
+
+* 1.15.1 (2014-02-13)
+
+ * fixed the conversion of the special '0000-00-00 00:00' date
+ * added an error message when trying to import an undefined block from a trait
+ * fixed a C extension crash when accessing defined but uninitialized property.
+
+* 1.15.0 (2013-12-06)
+
+ * made ignoreStrictCheck in Template::getAttribute() works with __call() methods throwing BadMethodCallException
+ * added min and max functions
+ * added the round filter
+ * fixed a bug that prevented the optimizers to be enabled/disabled selectively
+ * fixed first and last filters for UTF-8 strings
+ * added a source function to include the content of a template without rendering it
+ * fixed the C extension sandbox behavior when get or set is prepend to method name
+
+* 1.14.2 (2013-10-30)
+
+ * fixed error filename/line when an error occurs in an included file
+ * allowed operators that contain whitespaces to have more than one whitespace
+ * allowed tests to be made of 1 or 2 words (like "same as" or "divisible by")
+
+* 1.14.1 (2013-10-15)
+
+ * made it possible to use named operators as variables
+ * fixed the possibility to have a variable named 'matches'
+ * added support for PHP 5.5 DateTimeInterface
+
+* 1.14.0 (2013-10-03)
+
+ * fixed usage of the html_attr escaping strategy to avoid double-escaping with the html strategy
+ * added new operators: ends with, starts with, and matches
+ * fixed some compatibility issues with HHVM
+ * added a way to add custom escaping strategies
+ * fixed the C extension compilation on Windows
+ * fixed the batch filter when using a fill argument with an exact match of elements to batch
+ * fixed the filesystem loader cache when a template name exists in several namespaces
+ * fixed template_from_string when the template includes or extends other ones
+ * fixed a crash of the C extension on an edge case
+
+* 1.13.2 (2013-08-03)
+
+ * fixed the error line number for an error occurs in and embedded template
+ * fixed crashes of the C extension on some edge cases
+
+* 1.13.1 (2013-06-06)
+
+ * added the possibility to ignore the filesystem constructor argument in Twig_Loader_Filesystem
+ * fixed Twig_Loader_Chain::exists() for a loader which implements Twig_ExistsLoaderInterface
+ * adjusted backtrace call to reduce memory usage when an error occurs
+ * added support for object instances as the second argument of the constant test
+ * fixed the include function when used in an assignment
+
+* 1.13.0 (2013-05-10)
+
+ * fixed getting a numeric-like item on a variable ('09' for instance)
+ * fixed getting a boolean or float key on an array, so it is consistent with PHP's array access:
+ `{{ array[false] }}` behaves the same as `echo $array[false];` (equals `$array[0]`)
+ * made the escape filter 20% faster for happy path (escaping string for html with UTF-8)
+ * changed ☃ to § in tests
+ * enforced usage of named arguments after positional ones
+
+* 1.12.3 (2013-04-08)
+
+ * fixed a security issue in the filesystem loader where it was possible to include a template one
+ level above the configured path
+ * fixed fatal error that should be an exception when adding a filter/function/test too late
+ * added a batch filter
+ * added support for encoding an array as query string in the url_encode filter
+
+* 1.12.2 (2013-02-09)
+
+ * fixed the timezone used by the date filter and function when the given date contains a timezone (like 2010-01-28T15:00:00+02:00)
+ * fixed globals when getGlobals is called early on
+ * added the first and last filter
+
+* 1.12.1 (2013-01-15)
+
+ * added support for object instances as the second argument of the constant function
+ * relaxed globals management to avoid a BC break
+ * added support for {{ some_string[:2] }}
+
+* 1.12.0 (2013-01-08)
+
+ * added verbatim as an alias for the raw tag to avoid confusion with the raw filter
+ * fixed registration of tests and functions as anonymous functions
+ * fixed globals management
+
+* 1.12.0-RC1 (2012-12-29)
+
+ * added an include function (does the same as the include tag but in a more flexible way)
+ * added the ability to use any PHP callable to define filters, functions, and tests
+ * added a syntax error when using a loop variable that is not defined
+ * added the ability to set default values for macro arguments
+ * added support for named arguments for filters, tests, and functions
+ * moved filters/functions/tests syntax errors to the parser
+ * added support for extended ternary operator syntaxes
+
+* 1.11.1 (2012-11-11)
+
+ * fixed debug info line numbering (was off by 2)
+ * fixed escaping when calling a macro inside another one (regression introduced in 1.9.1)
+ * optimized variable access on PHP 5.4
+ * fixed a crash of the C extension when an exception was thrown from a macro called without being imported (using _self.XXX)
+
+* 1.11.0 (2012-11-07)
+
+ * fixed macro compilation when a variable name is a PHP reserved keyword
+ * changed the date filter behavior to always apply the default timezone, except if false is passed as the timezone
+ * fixed bitwise operator precedences
+ * added the template_from_string function
+ * fixed default timezone usage for the date function
+ * optimized the way Twig exceptions are managed (to make them faster)
+ * added Twig_ExistsLoaderInterface (implementing this interface in your loader make the chain loader much faster)
+
+* 1.10.3 (2012-10-19)
+
+ * fixed wrong template location in some error messages
+ * reverted a BC break introduced in 1.10.2
+ * added a split filter
+
+* 1.10.2 (2012-10-15)
+
+ * fixed macro calls on PHP 5.4
+
+* 1.10.1 (2012-10-15)
+
+ * made a speed optimization to macro calls when imported via the "import" tag
+ * fixed C extension compilation on Windows
+ * fixed a segfault in the C extension when using DateTime objects
+
+* 1.10.0 (2012-09-28)
+
+ * extracted functional tests framework to make it reusable for third-party extensions
+ * added namespaced templates support in Twig_Loader_Filesystem
+ * added Twig_Loader_Filesystem::prependPath()
+ * fixed an error when a token parser pass a closure as a test to the subparse() method
+
+* 1.9.2 (2012-08-25)
+
+ * fixed the in operator for objects that contain circular references
+ * fixed the C extension when accessing a public property of an object implementing the \ArrayAccess interface
+
+* 1.9.1 (2012-07-22)
+
+ * optimized macro calls when auto-escaping is on
+ * fixed wrong parent class for Twig_Function_Node
+ * made Twig_Loader_Chain more explicit about problems
+
+* 1.9.0 (2012-07-13)
+
+ * made the parsing independent of the template loaders
+ * fixed exception trace when an error occurs when rendering a child template
+ * added escaping strategies for CSS, URL, and HTML attributes
+ * fixed nested embed tag calls
+ * added the date_modify filter
+
+* 1.8.3 (2012-06-17)
+
+ * fixed paths in the filesystem loader when passing a path that ends with a slash or a backslash
+ * fixed escaping when a project defines a function named html or js
+ * fixed chmod mode to apply the umask correctly
+
+* 1.8.2 (2012-05-30)
+
+ * added the abs filter
+ * fixed a regression when using a number in template attributes
+ * fixed compiler when mbstring.func_overload is set to 2
+ * fixed DateTimeZone support in date filter
+
+* 1.8.1 (2012-05-17)
+
+ * fixed a regression when dealing with SimpleXMLElement instances in templates
+ * fixed "is_safe" value for the "dump" function when "html_errors" is not defined in php.ini
+ * switched to use mbstring whenever possible instead of iconv (you might need to update your encoding as mbstring and iconv encoding names sometimes differ)
+
+* 1.8.0 (2012-05-08)
+
+ * enforced interface when adding tests, filters, functions, and node visitors from extensions
+ * fixed a side-effect of the date filter where the timezone might be changed
+ * simplified usage of the autoescape tag; the only (optional) argument is now the escaping strategy or false (with a BC layer)
+ * added a way to dynamically change the auto-escaping strategy according to the template "filename"
+ * changed the autoescape option to also accept a supported escaping strategy (for BC, true is equivalent to html)
+ * added an embed tag
+
+* 1.7.0 (2012-04-24)
+
+ * fixed a PHP warning when using CIFS
+ * fixed template line number in some exceptions
+ * added an iterable test
+ * added an error when defining two blocks with the same name in a template
+ * added the preserves_safety option for filters
+ * fixed a PHP notice when trying to access a key on a non-object/array variable
+ * enhanced error reporting when the template file is an instance of SplFileInfo
+ * added Twig_Environment::mergeGlobals()
+ * added compilation checks to avoid misuses of the sandbox tag
+ * fixed filesystem loader freshness logic for high traffic websites
+ * fixed random function when charset is null
+
+* 1.6.5 (2012-04-11)
+
+ * fixed a regression when a template only extends another one without defining any blocks
+
+* 1.6.4 (2012-04-02)
+
+ * fixed PHP notice in Twig_Error::guessTemplateLine() introduced in 1.6.3
+ * fixed performance when compiling large files
+ * optimized parent template creation when the template does not use dynamic inheritance
+
+* 1.6.3 (2012-03-22)
+
+ * fixed usage of Z_ADDREF_P for PHP 5.2 in the C extension
+ * fixed compilation of numeric values used in templates when using a locale where the decimal separator is not a dot
+ * made the strategy used to guess the real template file name and line number in exception messages much faster and more accurate
+
+* 1.6.2 (2012-03-18)
+
+ * fixed sandbox mode when used with inheritance
+ * added preserveKeys support for the slice filter
+ * fixed the date filter when a DateTime instance is passed with a specific timezone
+ * added a trim filter
+
+* 1.6.1 (2012-02-29)
+
+ * fixed Twig C extension
+ * removed the creation of Twig_Markup instances when not needed
+ * added a way to set the default global timezone for dates
+ * fixed the slice filter on strings when the length is not specified
+ * fixed the creation of the cache directory in case of a race condition
+
+* 1.6.0 (2012-02-04)
+
+ * fixed raw blocks when used with the whitespace trim option
+ * made a speed optimization to macro calls when imported via the "from" tag
+ * fixed globals, parsers, visitors, filters, tests, and functions management in Twig_Environment when a new one or new extension is added
+ * fixed the attribute function when passing arguments
+ * added slice notation support for the [] operator (syntactic sugar for the slice operator)
+ * added a slice filter
+ * added string support for the reverse filter
+ * fixed the empty test and the length filter for Twig_Markup instances
+ * added a date function to ease date comparison
+ * fixed unary operators precedence
+ * added recursive parsing support in the parser
+ * added string and integer handling for the random function
+
+* 1.5.1 (2012-01-05)
+
+ * fixed a regression when parsing strings
+
+* 1.5.0 (2012-01-04)
+
+ * added Traversable objects support for the join filter
+
+* 1.5.0-RC2 (2011-12-30)
+
+ * added a way to set the default global date interval format
+ * fixed the date filter for DateInterval instances (setTimezone() does not exist for them)
+ * refactored Twig_Template::display() to ease its extension
+ * added a number_format filter
+
+* 1.5.0-RC1 (2011-12-26)
+
+ * removed the need to quote hash keys
+ * allowed hash keys to be any expression
+ * added a do tag
+ * added a flush tag
+ * added support for dynamically named filters and functions
+ * added a dump function to help debugging templates
+ * added a nl2br filter
+ * added a random function
+ * added a way to change the default format for the date filter
+ * fixed the lexer when an operator ending with a letter ends a line
+ * added string interpolation support
+ * enhanced exceptions for unknown filters, functions, tests, and tags
+
+* 1.4.0 (2011-12-07)
+
+ * fixed lexer when using big numbers (> PHP_INT_MAX)
+ * added missing preserveKeys argument to the reverse filter
+ * fixed macros containing filter tag calls
+
+* 1.4.0-RC2 (2011-11-27)
+
+ * removed usage of Reflection in Twig_Template::getAttribute()
+ * added a C extension that can optionally replace Twig_Template::getAttribute()
+ * added negative timestamp support to the date filter
+
+* 1.4.0-RC1 (2011-11-20)
+
+ * optimized variable access when using PHP 5.4
+ * changed the precedence of the .. operator to be more consistent with languages that implements such a feature like Ruby
+ * added an Exception to Twig_Loader_Array::isFresh() method when the template does not exist to be consistent with other loaders
+ * added Twig_Function_Node to allow more complex functions to have their own Node class
+ * added Twig_Filter_Node to allow more complex filters to have their own Node class
+ * added Twig_Test_Node to allow more complex tests to have their own Node class
+ * added a better error message when a template is empty but contain a BOM
+ * fixed "in" operator for empty strings
+ * fixed the "defined" test and the "default" filter (now works with more than one call (foo.bar.foo) and for both values of the strict_variables option)
+ * changed the way extensions are loaded (addFilter/addFunction/addGlobal/addTest/addNodeVisitor/addTokenParser/addExtension can now be called in any order)
+ * added Twig_Environment::display()
+ * made the escape filter smarter when the encoding is not supported by PHP
+ * added a convert_encoding filter
+ * moved all node manipulations outside the compile() Node method
+ * made several speed optimizations
+
+* 1.3.0 (2011-10-08)
+
+no changes
+
+* 1.3.0-RC1 (2011-10-04)
+
+ * added an optimization for the parent() function
+ * added cache reloading when auto_reload is true and an extension has been modified
+ * added the possibility to force the escaping of a string already marked as safe (instance of Twig_Markup)
+ * allowed empty templates to be used as traits
+ * added traits support for the "parent" function
+
+* 1.2.0 (2011-09-13)
+
+no changes
+
+* 1.2.0-RC1 (2011-09-10)
+
+ * enhanced the exception when a tag remains unclosed
+ * added support for empty Countable objects for the "empty" test
+ * fixed algorithm that determines if a template using inheritance is valid (no output between block definitions)
+ * added better support for encoding problems when escaping a string (available as of PHP 5.4)
+ * added a way to ignore a missing template when using the "include" tag ({% include "foo" ignore missing %})
+ * added support for an array of templates to the "include" and "extends" tags ({% include ['foo', 'bar'] %})
+ * added support for bitwise operators in expressions
+ * added the "attribute" function to allow getting dynamic attributes on variables
+ * added Twig_Loader_Chain
+ * added Twig_Loader_Array::setTemplate()
+ * added an optimization for the set tag when used to capture a large chunk of static text
+ * changed name regex to match PHP one "[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*" (works for blocks, tags, functions, filters, and macros)
+ * removed the possibility to use the "extends" tag from a block
+ * added "if" modifier support to "for" loops
+
+* 1.1.2 (2011-07-30)
+
+ * fixed json_encode filter on PHP 5.2
+ * fixed regression introduced in 1.1.1 ({{ block(foo|lower) }})
+ * fixed inheritance when using conditional parents
+ * fixed compilation of templates when the body of a child template is not empty
+ * fixed output when a macro throws an exception
+ * fixed a parsing problem when a large chunk of text is enclosed in a comment tag
+ * added PHPDoc for all Token parsers and Core extension functions
+
+* 1.1.1 (2011-07-17)
+
+ * added a performance optimization in the Optimizer (also helps to lower the number of nested level calls)
+ * made some performance improvement for some edge cases
+
+* 1.1.0 (2011-06-28)
+
+ * fixed json_encode filter
+
+* 1.1.0-RC3 (2011-06-24)
+
+ * fixed method case-sensitivity when using the sandbox mode
+ * added timezone support for the date filter
+ * fixed possible security problems with NUL bytes
+
+* 1.1.0-RC2 (2011-06-16)
+
+ * added an exception when the template passed to "use" is not a string
+ * made 'a.b is defined' not throw an exception if a is not defined (in strict mode)
+ * added {% line \d+ %} directive
+
+* 1.1.0-RC1 (2011-05-28)
+
+Flush your cache after upgrading.
+
+ * fixed date filter when using a timestamp
+ * fixed the defined test for some cases
+ * fixed a parsing problem when a large chunk of text is enclosed in a raw tag
+ * added support for horizontal reuse of template blocks (see docs for more information)
+ * added whitespace control modifier to all tags (see docs for more information)
+ * added null as an alias for none (the null test is also an alias for the none test now)
+ * made TRUE, FALSE, NONE equivalent to their lowercase counterparts
+ * wrapped all compilation and runtime exceptions with Twig_Error_Runtime and added logic to guess the template name and line
+ * moved display() method to Twig_Template (generated templates should now use doDisplay() instead)
+
+* 1.0.0 (2011-03-27)
+
+ * fixed output when using mbstring
+ * fixed duplicate call of methods when using the sandbox
+ * made the charset configurable for the escape filter
+
+* 1.0.0-RC2 (2011-02-21)
+
+ * changed the way {% set %} works when capturing (the content is now marked as safe)
+ * added support for macro name in the endmacro tag
+ * make Twig_Error compatible with PHP 5.3.0 >
+ * fixed an infinite loop on some Windows configurations
+ * fixed the "length" filter for numbers
+ * fixed Template::getAttribute() as properties in PHP are case sensitive
+ * removed coupling between Twig_Node and Twig_Template
+ * fixed the ternary operator precedence rule
+
+* 1.0.0-RC1 (2011-01-09)
+
+Backward incompatibilities:
+
+ * the "items" filter, which has been deprecated for quite a long time now, has been removed
+ * the "range" filter has been converted to a function: 0|range(10) -> range(0, 10)
+ * the "constant" filter has been converted to a function: {{ some_date|date('DATE_W3C'|constant) }} -> {{ some_date|date(constant('DATE_W3C')) }}
+ * the "cycle" filter has been converted to a function: {{ ['odd', 'even']|cycle(i) }} -> {{ cycle(['odd', 'even'], i) }}
+ * the "for" tag does not support "joined by" anymore
+ * the "autoescape" first argument is now "true"/"false" (instead of "on"/"off")
+ * the "parent" tag has been replaced by a "parent" function ({{ parent() }} instead of {% parent %})
+ * the "display" tag has been replaced by a "block" function ({{ block('title') }} instead of {% display title %})
+ * removed the grammar and simple token parser (moved to the Twig Extensions repository)
+
+Changes:
+
+ * added "needs_context" option for filters and functions (the context is then passed as a first argument)
+ * added global variables support
+ * made macros return their value instead of echoing directly (fixes calling a macro in sandbox mode)
+ * added the "from" tag to import macros as functions
+ * added support for functions (a function is just syntactic sugar for a getAttribute() call)
+ * made macros callable when sandbox mode is enabled
+ * added an exception when a macro uses a reserved name
+ * the "default" filter now uses the "empty" test instead of just checking for null
+ * added the "empty" test
+
+* 0.9.10 (2010-12-16)
+
+Backward incompatibilities:
+
+ * The Escaper extension is enabled by default, which means that all displayed
+ variables are now automatically escaped. You can revert to the previous
+ behavior by removing the extension via $env->removeExtension('escaper')
+ or just set the 'autoescape' option to 'false'.
+ * removed the "without loop" attribute for the "for" tag (not needed anymore
+ as the Optimizer take care of that for most cases)
+ * arrays and hashes have now a different syntax
+ * arrays keep the same syntax with square brackets: [1, 2]
+ * hashes now use curly braces (["a": "b"] should now be written as {"a": "b"})
+ * support for "arrays with keys" and "hashes without keys" is not supported anymore ([1, "foo": "bar"] or {"foo": "bar", 1})
+ * the i18n extension is now part of the Twig Extensions repository
+
+Changes:
+
+ * added the merge filter
+ * removed 'is_escaper' option for filters (a left over from the previous version) -- you must use 'is_safe' now instead
+ * fixed usage of operators as method names (like is, in, and not)
+ * changed the order of execution for node visitors
+ * fixed default() filter behavior when used with strict_variables set to on
+ * fixed filesystem loader compatibility with PHAR files
+ * enhanced error messages when an unexpected token is parsed in an expression
+ * fixed filename not being added to syntax error messages
+ * added the autoescape option to enable/disable autoescaping
+ * removed the newline after a comment (mimics PHP behavior)
+ * added a syntax error exception when parent block is used on a template that does not extend another one
+ * made the Escaper extension enabled by default
+ * fixed sandbox extension when used with auto output escaping
+ * fixed escaper when wrapping a Twig_Node_Print (the original class must be preserved)
+ * added an Optimizer extension (enabled by default; optimizes "for" loops and "raw" filters)
+ * added priority to node visitors
+
+* 0.9.9 (2010-11-28)
+
+Backward incompatibilities:
+ * the self special variable has been renamed to _self
+ * the odd and even filters are now tests:
+ {{ foo|odd }} must now be written {{ foo is odd }}
+ * the "safe" filter has been renamed to "raw"
+ * in Node classes,
+ sub-nodes are now accessed via getNode() (instead of property access)
+ attributes via getAttribute() (instead of array access)
+ * the urlencode filter had been renamed to url_encode
+ * the include tag now merges the passed variables with the current context by default
+ (the old behavior is still possible by adding the "only" keyword)
+ * moved Exceptions to Twig_Error_* (Twig_SyntaxError/Twig_RuntimeError are now Twig_Error_Syntax/Twig_Error_Runtime)
+ * removed support for {{ 1 < i < 3 }} (use {{ i > 1 and i < 3 }} instead)
+ * the "in" filter has been removed ({{ a|in(b) }} should now be written {{ a in b }})
+
+Changes:
+ * added file and line to Twig_Error_Runtime exceptions thrown from Twig_Template
+ * changed trans tag to accept any variable for the plural count
+ * fixed sandbox mode (__toString() method check was not enforced if called implicitly from complex statements)
+ * added the ** (power) operator
+ * changed the algorithm used for parsing expressions
+ * added the spaceless tag
+ * removed trim_blocks option
+ * added support for is*() methods for attributes (foo.bar now looks for foo->getBar() or foo->isBar())
+ * changed all exceptions to extend Twig_Error
+ * fixed unary expressions ({{ not(1 or 0) }})
+ * fixed child templates (with an extend tag) that uses one or more imports
+ * added support for {{ 1 not in [2, 3] }} (more readable than the current {{ not (1 in [2, 3]) }})
+ * escaping has been rewritten
+ * the implementation of template inheritance has been rewritten
+ (blocks can now be called individually and still work with inheritance)
+ * fixed error handling for if tag when a syntax error occurs within a subparse process
+ * added a way to implement custom logic for resolving token parsers given a tag name
+ * fixed js escaper to be stricter (now uses a whilelist-based js escaper)
+ * added the following filers: "constant", "trans", "replace", "json_encode"
+ * added a "constant" test
+ * fixed objects with __toString() not being autoescaped
+ * fixed subscript expressions when calling __call() (methods now keep the case)
+ * added "test" feature (accessible via the "is" operator)
+ * removed the debug tag (should be done in an extension)
+ * fixed trans tag when no vars are used in plural form
+ * fixed race condition when writing template cache
+ * added the special _charset variable to reference the current charset
+ * added the special _context variable to reference the current context
+ * renamed self to _self (to avoid conflict)
+ * fixed Twig_Template::getAttribute() for protected properties
+
+* 0.9.8 (2010-06-28)
+
+Backward incompatibilities:
+ * the trans tag plural count is now attached to the plural tag:
+ old: `{% trans count %}...{% plural %}...{% endtrans %}`
+ new: `{% trans %}...{% plural count %}...{% endtrans %}`
+
+ * added a way to translate strings coming from a variable ({% trans var %})
+ * fixed trans tag when used with the Escaper extension
+ * fixed default cache umask
+ * removed Twig_Template instances from the debug tag output
+ * fixed objects with __isset() defined
+ * fixed set tag when used with a capture
+ * fixed type hinting for Twig_Environment::addFilter() method
+
+* 0.9.7 (2010-06-12)
+
+Backward incompatibilities:
+ * changed 'as' to '=' for the set tag ({% set title as "Title" %} must now be {% set title = "Title" %})
+ * removed the sandboxed attribute of the include tag (use the new sandbox tag instead)
+ * refactored the Node system (if you have custom nodes, you will have to update them to use the new API)
+
+ * added self as a special variable that refers to the current template (useful for importing macros from the current template)
+ * added Twig_Template instance support to the include tag
+ * added support for dynamic and conditional inheritance ({% extends some_var %} and {% extends standalone ? "minimum" : "base" %})
+ * added a grammar sub-framework to ease the creation of custom tags
+ * fixed the for tag for large arrays (some loop variables are now only available for arrays and objects that implement the Countable interface)
+ * removed the Twig_Resource::resolveMissingFilter() method
+ * fixed the filter tag which did not apply filtering to included files
+ * added a bunch of unit tests
+ * added a bunch of phpdoc
+ * added a sandbox tag in the sandbox extension
+ * changed the date filter to support any date format supported by DateTime
+ * added strict_variable setting to throw an exception when an invalid variable is used in a template (disabled by default)
+ * added the lexer, parser, and compiler as arguments to the Twig_Environment constructor
+ * changed the cache option to only accepts an explicit path to a cache directory or false
+ * added a way to add token parsers, filters, and visitors without creating an extension
+ * added three interfaces: Twig_NodeInterface, Twig_TokenParserInterface, and Twig_FilterInterface
+ * changed the generated code to match the new coding standards
+ * fixed sandbox mode (__toString() method check was not enforced if called implicitly from a simple statement like {{ article }})
+ * added an exception when a child template has a non-empty body (as it is always ignored when rendering)
+
+* 0.9.6 (2010-05-12)
+
+ * fixed variables defined outside a loop and for which the value changes in a for loop
+ * fixed the test suite for PHP 5.2 and older versions of PHPUnit
+ * added support for __call() in expression resolution
+ * fixed node visiting for macros (macros are now visited by visitors as any other node)
+ * fixed nested block definitions with a parent call (rarely useful but nonetheless supported now)
+ * added the cycle filter
+ * fixed the Lexer when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII
+ * added a long-syntax for the set tag ({% set foo %}...{% endset %})
+ * unit tests are now powered by PHPUnit
+ * added support for gettext via the `i18n` extension
+ * fixed twig_capitalize_string_filter() and fixed twig_length_filter() when used with UTF-8 values
+ * added a more useful exception if an if tag is not closed properly
+ * added support for escaping strategy in the autoescape tag
+ * fixed lexer when a template has a big chunk of text between/in a block
+
+* 0.9.5 (2010-01-20)
+
+As for any new release, don't forget to remove all cached templates after
+upgrading.
+
+If you have defined custom filters, you MUST upgrade them for this release. To
+upgrade, replace "array" with "new Twig_Filter_Function", and replace the
+environment constant by the "needs_environment" option:
+
+ // before
+ 'even' => array('twig_is_even_filter', false),
+ 'escape' => array('twig_escape_filter', true),
+
+ // after
+ 'even' => new Twig_Filter_Function('twig_is_even_filter'),
+ 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)),
+
+If you have created NodeTransformer classes, you will need to upgrade them to
+the new interface (please note that the interface is not yet considered
+stable).
+
+ * fixed list nodes that did not extend the Twig_NodeListInterface
+ * added the "without loop" option to the for tag (it disables the generation of the loop variable)
+ * refactored node transformers to node visitors
+ * fixed automatic-escaping for blocks
+ * added a way to specify variables to pass to an included template
+ * changed the automatic-escaping rules to be more sensible and more configurable in custom filters (the documentation lists all the rules)
+ * improved the filter system to allow object methods to be used as filters
+ * changed the Array and String loaders to actually make use of the cache mechanism
+ * included the default filter function definitions in the extension class files directly (Core, Escaper)
+ * added the // operator (like the floor() PHP function)
+ * added the .. operator (as a syntactic sugar for the range filter when the step is 1)
+ * added the in operator (as a syntactic sugar for the in filter)
+ * added the following filters in the Core extension: in, range
+ * added support for arrays (same behavior as in PHP, a mix between lists and dictionaries, arrays and hashes)
+ * enhanced some error messages to provide better feedback in case of parsing errors
+
+* 0.9.4 (2009-12-02)
+
+If you have custom loaders, you MUST upgrade them for this release: The
+Twig_Loader base class has been removed, and the Twig_LoaderInterface has also
+been changed (see the source code for more information or the documentation).
+
+ * added support for DateTime instances for the date filter
+ * fixed loop.last when the array only has one item
+ * made it possible to insert newlines in tag and variable blocks
+ * fixed a bug when a literal '\n' were present in a template text
+ * fixed bug when the filename of a template contains */
+ * refactored loaders
+
+* 0.9.3 (2009-11-11)
+
+This release is NOT backward compatible with the previous releases.
+
+ The loaders do not take the cache and autoReload arguments anymore. Instead,
+ the Twig_Environment class has two new options: cache and auto_reload.
+ Upgrading your code means changing this kind of code:
+
+ $loader = new Twig_Loader_Filesystem('/path/to/templates', '/path/to/compilation_cache', true);
+ $twig = new Twig_Environment($loader);
+
+ to something like this:
+
+ $loader = new Twig_Loader_Filesystem('/path/to/templates');
+ $twig = new Twig_Environment($loader, array(
+ 'cache' => '/path/to/compilation_cache',
+ 'auto_reload' => true,
+ ));
+
+ * deprecated the "items" filter as it is not needed anymore
+ * made cache and auto_reload options of Twig_Environment instead of arguments of Twig_Loader
+ * optimized template loading speed
+ * removed output when an error occurs in a template and render() is used
+ * made major speed improvements for loops (up to 300% on even the smallest loops)
+ * added properties as part of the sandbox mode
+ * added public properties support (obj.item can now be the item property on the obj object)
+ * extended set tag to support expression as value ({% set foo as 'foo' ~ 'bar' %} )
+ * fixed bug when \ was used in HTML
+
+* 0.9.2 (2009-10-29)
+
+ * made some speed optimizations
+ * changed the cache extension to .php
+ * added a js escaping strategy
+ * added support for short block tag
+ * changed the filter tag to allow chained filters
+ * made lexer more flexible as you can now change the default delimiters
+ * added set tag
+ * changed default directory permission when cache dir does not exist (more secure)
+ * added macro support
+ * changed filters first optional argument to be a Twig_Environment instance instead of a Twig_Template instance
+ * made Twig_Autoloader::autoload() a static method
+ * avoid writing template file if an error occurs
+ * added $ escaping when outputting raw strings
+ * enhanced some error messages to ease debugging
+ * fixed empty cache files when the template contains an error
+
+* 0.9.1 (2009-10-14)
+
+ * fixed a bug in PHP 5.2.6
+ * fixed numbers with one than one decimal
+ * added support for method calls with arguments ({{ foo.bar('a', 43) }})
+ * made small speed optimizations
+ * made minor tweaks to allow better extensibility and flexibility
+
+* 0.9.0 (2009-10-12)
+
+ * Initial release
diff --git a/src/composer/vendor/twig/twig/LICENSE b/src/composer/vendor/twig/twig/LICENSE
new file mode 100644
index 00000000..cc74f810
--- /dev/null
+++ b/src/composer/vendor/twig/twig/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2009-2016 by the Twig Team.
+
+Some 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.
+
+ * The names of the contributors may not be used to endorse or
+ promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/composer/vendor/twig/twig/README.rst b/src/composer/vendor/twig/twig/README.rst
new file mode 100644
index 00000000..81737b0b
--- /dev/null
+++ b/src/composer/vendor/twig/twig/README.rst
@@ -0,0 +1,15 @@
+Twig, the flexible, fast, and secure template language for PHP
+==============================================================
+
+Twig is a template language for PHP, released under the new BSD license (code
+and documentation).
+
+Twig uses a syntax similar to the Django and Jinja template languages which
+inspired the Twig runtime environment.
+
+More Information
+----------------
+
+Read the `documentation`_ for more information.
+
+.. _documentation: http://twig.sensiolabs.org/documentation
diff --git a/src/composer/vendor/twig/twig/composer.json b/src/composer/vendor/twig/twig/composer.json
new file mode 100644
index 00000000..339a5d4d
--- /dev/null
+++ b/src/composer/vendor/twig/twig/composer.json
@@ -0,0 +1,46 @@
+{
+ "name": "twig/twig",
+ "type": "library",
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "keywords": ["templating"],
+ "homepage": "http://twig.sensiolabs.org",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Twig Team",
+ "homepage": "http://twig.sensiolabs.org/contributors",
+ "role": "Contributors"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ }
+ ],
+ "support": {
+ "forum": "https://groups.google.com/forum/#!forum/twig-users"
+ },
+ "require": {
+ "php": ">=5.2.7"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7",
+ "symfony/debug": "~2.7"
+ },
+ "autoload": {
+ "psr-0" : {
+ "Twig_" : "lib/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.23-dev"
+ }
+ }
+}
diff --git a/src/composer/vendor/twig/twig/doc/advanced.rst b/src/composer/vendor/twig/twig/doc/advanced.rst
new file mode 100644
index 00000000..5b436ff2
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/advanced.rst
@@ -0,0 +1,872 @@
+Extending Twig
+==============
+
+.. caution::
+
+ This section describes how to extend Twig as of **Twig 1.12**. If you are
+ using an older version, read the :doc:`legacy` chapter
+ instead.
+
+Twig can be extended in many ways; you can add extra tags, filters, tests,
+operators, global variables, and functions. You can even extend the parser
+itself with node visitors.
+
+.. note::
+
+ The first section of this chapter describes how to extend Twig easily. If
+ you want to reuse your changes in different projects or if you want to
+ share them with others, you should then create an extension as described
+ in the following section.
+
+.. caution::
+
+ When extending Twig without creating an extension, Twig won't be able to
+ recompile your templates when the PHP code is updated. To see your changes
+ in real-time, either disable template caching or package your code into an
+ extension (see the next section of this chapter).
+
+Before extending Twig, you must understand the differences between all the
+different possible extension points and when to use them.
+
+First, remember that Twig has two main language constructs:
+
+* ``{{ }}``: used to print the result of an expression evaluation;
+
+* ``{% %}``: used to execute statements.
+
+To understand why Twig exposes so many extension points, let's see how to
+implement a *Lorem ipsum* generator (it needs to know the number of words to
+generate).
+
+You can use a ``lipsum`` *tag*:
+
+.. code-block:: jinja
+
+ {% lipsum 40 %}
+
+That works, but using a tag for ``lipsum`` is not a good idea for at least
+three main reasons:
+
+* ``lipsum`` is not a language construct;
+* The tag outputs something;
+* The tag is not flexible as you cannot use it in an expression:
+
+ .. code-block:: jinja
+
+ {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }}
+
+In fact, you rarely need to create tags; and that's good news because tags are
+the most complex extension point of Twig.
+
+Now, let's use a ``lipsum`` *filter*:
+
+.. code-block:: jinja
+
+ {{ 40|lipsum }}
+
+Again, it works, but it looks weird. A filter transforms the passed value to
+something else but here we use the value to indicate the number of words to
+generate (so, ``40`` is an argument of the filter, not the value we want to
+transform).
+
+Next, let's use a ``lipsum`` *function*:
+
+.. code-block:: jinja
+
+ {{ lipsum(40) }}
+
+Here we go. For this specific example, the creation of a function is the
+extension point to use. And you can use it anywhere an expression is accepted:
+
+.. code-block:: jinja
+
+ {{ 'some text' ~ lipsum(40) ~ 'some more text' }}
+
+ {% set lipsum = lipsum(40) %}
+
+Last but not the least, you can also use a *global* object with a method able
+to generate lorem ipsum text:
+
+.. code-block:: jinja
+
+ {{ text.lipsum(40) }}
+
+As a rule of thumb, use functions for frequently used features and global
+objects for everything else.
+
+Keep in mind the following when you want to extend Twig:
+
+========== ========================== ========== =========================
+What? Implementation difficulty? How often? When?
+========== ========================== ========== =========================
+*macro* trivial frequent Content generation
+*global* trivial frequent Helper object
+*function* trivial frequent Content generation
+*filter* trivial frequent Value transformation
+*tag* complex rare DSL language construct
+*test* trivial rare Boolean decision
+*operator* trivial rare Values transformation
+========== ========================== ========== =========================
+
+Globals
+-------
+
+A global variable is like any other template variable, except that it's
+available in all templates and macros::
+
+ $twig = new Twig_Environment($loader);
+ $twig->addGlobal('text', new Text());
+
+You can then use the ``text`` variable anywhere in a template:
+
+.. code-block:: jinja
+
+ {{ text.lipsum(40) }}
+
+Filters
+-------
+
+Creating a filter is as simple as associating a name with a PHP callable::
+
+ // an anonymous function
+ $filter = new Twig_SimpleFilter('rot13', function ($string) {
+ return str_rot13($string);
+ });
+
+ // or a simple PHP function
+ $filter = new Twig_SimpleFilter('rot13', 'str_rot13');
+
+ // or a class method
+ $filter = new Twig_SimpleFilter('rot13', array('SomeClass', 'rot13Filter'));
+
+The first argument passed to the ``Twig_SimpleFilter`` constructor is the name
+of the filter you will use in templates and the second one is the PHP callable
+to associate with it.
+
+Then, add the filter to your Twig environment::
+
+ $twig = new Twig_Environment($loader);
+ $twig->addFilter($filter);
+
+And here is how to use it in a template:
+
+.. code-block:: jinja
+
+ {{ 'Twig'|rot13 }}
+
+ {# will output Gjvt #}
+
+When called by Twig, the PHP callable receives the left side of the filter
+(before the pipe ``|``) as the first argument and the extra arguments passed
+to the filter (within parentheses ``()``) as extra arguments.
+
+For instance, the following code:
+
+.. code-block:: jinja
+
+ {{ 'TWIG'|lower }}
+ {{ now|date('d/m/Y') }}
+
+is compiled to something like the following::
+
+
+
+
+The ``Twig_SimpleFilter`` class takes an array of options as its last
+argument::
+
+ $filter = new Twig_SimpleFilter('rot13', 'str_rot13', $options);
+
+Environment-aware Filters
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you want to access the current environment instance in your filter, set the
+``needs_environment`` option to ``true``; Twig will pass the current
+environment as the first argument to the filter call::
+
+ $filter = new Twig_SimpleFilter('rot13', function (Twig_Environment $env, $string) {
+ // get the current charset for instance
+ $charset = $env->getCharset();
+
+ return str_rot13($string);
+ }, array('needs_environment' => true));
+
+Context-aware Filters
+~~~~~~~~~~~~~~~~~~~~~
+
+If you want to access the current context in your filter, set the
+``needs_context`` option to ``true``; Twig will pass the current context as
+the first argument to the filter call (or the second one if
+``needs_environment`` is also set to ``true``)::
+
+ $filter = new Twig_SimpleFilter('rot13', function ($context, $string) {
+ // ...
+ }, array('needs_context' => true));
+
+ $filter = new Twig_SimpleFilter('rot13', function (Twig_Environment $env, $context, $string) {
+ // ...
+ }, array('needs_context' => true, 'needs_environment' => true));
+
+Automatic Escaping
+~~~~~~~~~~~~~~~~~~
+
+If automatic escaping is enabled, the output of the filter may be escaped
+before printing. If your filter acts as an escaper (or explicitly outputs HTML
+or JavaScript code), you will want the raw output to be printed. In such a
+case, set the ``is_safe`` option::
+
+ $filter = new Twig_SimpleFilter('nl2br', 'nl2br', array('is_safe' => array('html')));
+
+Some filters may need to work on input that is already escaped or safe, for
+example when adding (safe) HTML tags to originally unsafe output. In such a
+case, set the ``pre_escape`` option to escape the input data before it is run
+through your filter::
+
+ $filter = new Twig_SimpleFilter('somefilter', 'somefilter', array('pre_escape' => 'html', 'is_safe' => array('html')));
+
+Variadic Filters
+~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.19
+ Support for variadic filters was added in Twig 1.19.
+
+When a filter should accept an arbitrary number of arguments, set the
+``is_variadic`` option to ``true``; Twig will pass the extra arguments as the
+last argument to the filter call as an array::
+
+ $filter = new Twig_SimpleFilter('thumbnail', function ($file, array $options = array()) {
+ // ...
+ }, array('is_variadic' => true));
+
+Be warned that named arguments passed to a variadic filter cannot be checked
+for validity as they will automatically end up in the option array.
+
+Dynamic Filters
+~~~~~~~~~~~~~~~
+
+A filter name containing the special ``*`` character is a dynamic filter as
+the ``*`` can be any string::
+
+ $filter = new Twig_SimpleFilter('*_path', function ($name, $arguments) {
+ // ...
+ });
+
+The following filters will be matched by the above defined dynamic filter:
+
+* ``product_path``
+* ``category_path``
+
+A dynamic filter can define more than one dynamic parts::
+
+ $filter = new Twig_SimpleFilter('*_path_*', function ($name, $suffix, $arguments) {
+ // ...
+ });
+
+The filter will receive all dynamic part values before the normal filter
+arguments, but after the environment and the context. For instance, a call to
+``'foo'|a_path_b()`` will result in the following arguments to be passed to
+the filter: ``('a', 'b', 'foo')``.
+
+Deprecated Filters
+~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.21
+ Support for deprecated filters was added in Twig 1.21.
+
+You can mark a filter as being deprecated by setting the ``deprecated`` option
+to ``true``. You can also give an alternative filter that replaces the
+deprecated one when that makes sense::
+
+ $filter = new Twig_SimpleFilter('obsolete', function () {
+ // ...
+ }, array('deprecated' => true, 'alternative' => 'new_one'));
+
+When a filter is deprecated, Twig emits a deprecation notice when compiling a
+template using it. See :ref:`deprecation-notices` for more information.
+
+Functions
+---------
+
+Functions are defined in the exact same way as filters, but you need to create
+an instance of ``Twig_SimpleFunction``::
+
+ $twig = new Twig_Environment($loader);
+ $function = new Twig_SimpleFunction('function_name', function () {
+ // ...
+ });
+ $twig->addFunction($function);
+
+Functions support the same features as filters, except for the ``pre_escape``
+and ``preserves_safety`` options.
+
+Tests
+-----
+
+Tests are defined in the exact same way as filters and functions, but you need
+to create an instance of ``Twig_SimpleTest``::
+
+ $twig = new Twig_Environment($loader);
+ $test = new Twig_SimpleTest('test_name', function () {
+ // ...
+ });
+ $twig->addTest($test);
+
+Tests allow you to create custom application specific logic for evaluating
+boolean conditions. As a simple example, let's create a Twig test that checks if
+objects are 'red'::
+
+ $twig = new Twig_Environment($loader);
+ $test = new Twig_SimpleTest('red', function ($value) {
+ if (isset($value->color) && $value->color == 'red') {
+ return true;
+ }
+ if (isset($value->paint) && $value->paint == 'red') {
+ return true;
+ }
+ return false;
+ });
+ $twig->addTest($test);
+
+Test functions should always return true/false.
+
+When creating tests you can use the ``node_class`` option to provide custom test
+compilation. This is useful if your test can be compiled into PHP primitives.
+This is used by many of the tests built into Twig::
+
+ $twig = new Twig_Environment($loader);
+ $test = new Twig_SimpleTest(
+ 'odd',
+ null,
+ array('node_class' => 'Twig_Node_Expression_Test_Odd'));
+ $twig->addTest($test);
+
+ class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test
+ {
+ public function compile(Twig_Compiler $compiler)
+ {
+ $compiler
+ ->raw('(')
+ ->subcompile($this->getNode('node'))
+ ->raw(' % 2 == 1')
+ ->raw(')')
+ ;
+ }
+ }
+
+The above example shows how you can create tests that use a node class. The
+node class has access to one sub-node called 'node'. This sub-node contains the
+value that is being tested. When the ``odd`` filter is used in code such as:
+
+.. code-block:: jinja
+
+ {% if my_value is odd %}
+
+The ``node`` sub-node will contain an expression of ``my_value``. Node-based
+tests also have access to the ``arguments`` node. This node will contain the
+various other arguments that have been provided to your test.
+
+If you want to pass a variable number of positional or named arguments to the
+test, set the ``is_variadic`` option to ``true``. Tests also support dynamic
+name feature as filters and functions.
+
+Tags
+----
+
+One of the most exciting features of a template engine like Twig is the
+possibility to define new language constructs. This is also the most complex
+feature as you need to understand how Twig's internals work.
+
+Let's create a simple ``set`` tag that allows the definition of simple
+variables from within a template. The tag can be used like follows:
+
+.. code-block:: jinja
+
+ {% set name = "value" %}
+
+ {{ name }}
+
+ {# should output value #}
+
+.. note::
+
+ The ``set`` tag is part of the Core extension and as such is always
+ available. The built-in version is slightly more powerful and supports
+ multiple assignments by default (cf. the template designers chapter for
+ more information).
+
+Three steps are needed to define a new tag:
+
+* Defining a Token Parser class (responsible for parsing the template code);
+
+* Defining a Node class (responsible for converting the parsed code to PHP);
+
+* Registering the tag.
+
+Registering a new tag
+~~~~~~~~~~~~~~~~~~~~~
+
+Adding a tag is as simple as calling the ``addTokenParser`` method on the
+``Twig_Environment`` instance::
+
+ $twig = new Twig_Environment($loader);
+ $twig->addTokenParser(new Project_Set_TokenParser());
+
+Defining a Token Parser
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Now, let's see the actual code of this class::
+
+ class Project_Set_TokenParser extends Twig_TokenParser
+ {
+ public function parse(Twig_Token $token)
+ {
+ $parser = $this->parser;
+ $stream = $parser->getStream();
+
+ $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
+ $stream->expect(Twig_Token::OPERATOR_TYPE, '=');
+ $value = $parser->getExpressionParser()->parseExpression();
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+
+ return new Project_Set_Node($name, $value, $token->getLine(), $this->getTag());
+ }
+
+ public function getTag()
+ {
+ return 'set';
+ }
+ }
+
+The ``getTag()`` method must return the tag we want to parse, here ``set``.
+
+The ``parse()`` method is invoked whenever the parser encounters a ``set``
+tag. It should return a ``Twig_Node`` instance that represents the node (the
+``Project_Set_Node`` calls creating is explained in the next section).
+
+The parsing process is simplified thanks to a bunch of methods you can call
+from the token stream (``$this->parser->getStream()``):
+
+* ``getCurrent()``: Gets the current token in the stream.
+
+* ``next()``: Moves to the next token in the stream, *but returns the old one*.
+
+* ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether
+ the current token is of a particular type or value (or both). The value may be an
+ array of several possible values.
+
+* ``expect($type[, $value[, $message]])``: If the current token isn't of the given
+ type/value a syntax error is thrown. Otherwise, if the type and value are correct,
+ the token is returned and the stream moves to the next token.
+
+* ``look()``: Looks a the next token without consuming it.
+
+Parsing expressions is done by calling the ``parseExpression()`` like we did for
+the ``set`` tag.
+
+.. tip::
+
+ Reading the existing ``TokenParser`` classes is the best way to learn all
+ the nitty-gritty details of the parsing process.
+
+Defining a Node
+~~~~~~~~~~~~~~~
+
+The ``Project_Set_Node`` class itself is rather simple::
+
+ class Project_Set_Node extends Twig_Node
+ {
+ public function __construct($name, Twig_Node_Expression $value, $line, $tag = null)
+ {
+ parent::__construct(array('value' => $value), array('name' => $name), $line, $tag);
+ }
+
+ public function compile(Twig_Compiler $compiler)
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->write('$context[\''.$this->getAttribute('name').'\'] = ')
+ ->subcompile($this->getNode('value'))
+ ->raw(";\n")
+ ;
+ }
+ }
+
+The compiler implements a fluid interface and provides methods that helps the
+developer generate beautiful and readable PHP code:
+
+* ``subcompile()``: Compiles a node.
+
+* ``raw()``: Writes the given string as is.
+
+* ``write()``: Writes the given string by adding indentation at the beginning
+ of each line.
+
+* ``string()``: Writes a quoted string.
+
+* ``repr()``: Writes a PHP representation of a given value (see
+ ``Twig_Node_For`` for a usage example).
+
+* ``addDebugInfo()``: Adds the line of the original template file related to
+ the current node as a comment.
+
+* ``indent()``: Indents the generated code (see ``Twig_Node_Block`` for a
+ usage example).
+
+* ``outdent()``: Outdents the generated code (see ``Twig_Node_Block`` for a
+ usage example).
+
+.. _creating_extensions:
+
+Creating an Extension
+---------------------
+
+The main motivation for writing an extension is to move often used code into a
+reusable class like adding support for internationalization. An extension can
+define tags, filters, tests, operators, global variables, functions, and node
+visitors.
+
+Creating an extension also makes for a better separation of code that is
+executed at compilation time and code needed at runtime. As such, it makes
+your code faster.
+
+Most of the time, it is useful to create a single extension for your project,
+to host all the specific tags and filters you want to add to Twig.
+
+.. tip::
+
+ When packaging your code into an extension, Twig is smart enough to
+ recompile your templates whenever you make a change to it (when
+ ``auto_reload`` is enabled).
+
+.. note::
+
+ Before writing your own extensions, have a look at the Twig official
+ extension repository: http://github.com/twigphp/Twig-extensions.
+
+An extension is a class that implements the following interface::
+
+ interface Twig_ExtensionInterface
+ {
+ /**
+ * Initializes the runtime environment.
+ *
+ * This is where you can load some file that contains filter functions for instance.
+ *
+ * @param Twig_Environment $environment The current Twig_Environment instance
+ *
+ * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_InitRuntimeInterface instead
+ */
+ function initRuntime(Twig_Environment $environment);
+
+ /**
+ * Returns the token parser instances to add to the existing list.
+ *
+ * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
+ */
+ function getTokenParsers();
+
+ /**
+ * Returns the node visitor instances to add to the existing list.
+ *
+ * @return array An array of Twig_NodeVisitorInterface instances
+ */
+ function getNodeVisitors();
+
+ /**
+ * Returns a list of filters to add to the existing list.
+ *
+ * @return array An array of filters
+ */
+ function getFilters();
+
+ /**
+ * Returns a list of tests to add to the existing list.
+ *
+ * @return array An array of tests
+ */
+ function getTests();
+
+ /**
+ * Returns a list of functions to add to the existing list.
+ *
+ * @return array An array of functions
+ */
+ function getFunctions();
+
+ /**
+ * Returns a list of operators to add to the existing list.
+ *
+ * @return array An array of operators
+ */
+ function getOperators();
+
+ /**
+ * Returns a list of global variables to add to the existing list.
+ *
+ * @return array An array of global variables
+ *
+ * @deprecated since 1.23 (to be removed in 2.0), implement Twig_Extension_GlobalsInterface instead
+ */
+ function getGlobals();
+
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ */
+ function getName();
+ }
+
+To keep your extension class clean and lean, it can inherit from the built-in
+``Twig_Extension`` class instead of implementing the whole interface. That
+way, you just need to implement the ``getName()`` method as the
+``Twig_Extension`` provides empty implementations for all other methods.
+
+The ``getName()`` method must return a unique identifier for your extension.
+
+Now, with this information in mind, let's create the most basic extension
+possible::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getName()
+ {
+ return 'project';
+ }
+ }
+
+.. note::
+
+ Of course, this extension does nothing for now. We will customize it in
+ the next sections.
+
+Twig does not care where you save your extension on the filesystem, as all
+extensions must be registered explicitly to be available in your templates.
+
+You can register an extension by using the ``addExtension()`` method on your
+main ``Environment`` object::
+
+ $twig = new Twig_Environment($loader);
+ $twig->addExtension(new Project_Twig_Extension());
+
+.. tip::
+
+ The bundled extensions are great examples of how extensions work.
+
+Globals
+~~~~~~~
+
+Global variables can be registered in an extension via the ``getGlobals()``
+method::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getGlobals()
+ {
+ return array(
+ 'text' => new Text(),
+ );
+ }
+
+ // ...
+ }
+
+Functions
+~~~~~~~~~
+
+Functions can be registered in an extension via the ``getFunctions()``
+method::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getFunctions()
+ {
+ return array(
+ new Twig_SimpleFunction('lipsum', 'generate_lipsum'),
+ );
+ }
+
+ // ...
+ }
+
+Filters
+~~~~~~~
+
+To add a filter to an extension, you need to override the ``getFilters()``
+method. This method must return an array of filters to add to the Twig
+environment::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getFilters()
+ {
+ return array(
+ new Twig_SimpleFilter('rot13', 'str_rot13'),
+ );
+ }
+
+ // ...
+ }
+
+Tags
+~~~~
+
+Adding a tag in an extension can be done by overriding the
+``getTokenParsers()`` method. This method must return an array of tags to add
+to the Twig environment::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getTokenParsers()
+ {
+ return array(new Project_Set_TokenParser());
+ }
+
+ // ...
+ }
+
+In the above code, we have added a single new tag, defined by the
+``Project_Set_TokenParser`` class. The ``Project_Set_TokenParser`` class is
+responsible for parsing the tag and compiling it to PHP.
+
+Operators
+~~~~~~~~~
+
+The ``getOperators()`` methods lets you add new operators. Here is how to add
+``!``, ``||``, and ``&&`` operators::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getOperators()
+ {
+ return array(
+ array(
+ '!' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'),
+ ),
+ array(
+ '||' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '&&' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ ),
+ );
+ }
+
+ // ...
+ }
+
+Tests
+~~~~~
+
+The ``getTests()`` method lets you add new test functions::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getTests()
+ {
+ return array(
+ new Twig_SimpleTest('even', 'twig_test_even'),
+ );
+ }
+
+ // ...
+ }
+
+Overloading
+-----------
+
+To overload an already defined filter, test, operator, global variable, or
+function, re-define it in an extension and register it **as late as
+possible** (order matters)::
+
+ class MyCoreExtension extends Twig_Extension
+ {
+ public function getFilters()
+ {
+ return array(
+ new Twig_SimpleFilter('date', array($this, 'dateFilter')),
+ );
+ }
+
+ public function dateFilter($timestamp, $format = 'F j, Y H:i')
+ {
+ // do something different from the built-in date filter
+ }
+
+ public function getName()
+ {
+ return 'project';
+ }
+ }
+
+ $twig = new Twig_Environment($loader);
+ $twig->addExtension(new MyCoreExtension());
+
+Here, we have overloaded the built-in ``date`` filter with a custom one.
+
+If you do the same on the Twig_Environment itself, beware that it takes
+precedence over any other registered extensions::
+
+ $twig = new Twig_Environment($loader);
+ $twig->addFilter(new Twig_SimpleFilter('date', function ($timestamp, $format = 'F j, Y H:i') {
+ // do something different from the built-in date filter
+ }));
+ // the date filter will come from the above registration, not
+ // from the registered extension below
+ $twig->addExtension(new MyCoreExtension());
+
+.. caution::
+
+ Note that overloading the built-in Twig elements is not recommended as it
+ might be confusing.
+
+Testing an Extension
+--------------------
+
+Functional Tests
+~~~~~~~~~~~~~~~~
+
+You can create functional tests for extensions simply by creating the
+following file structure in your test directory::
+
+ Fixtures/
+ filters/
+ foo.test
+ bar.test
+ functions/
+ foo.test
+ bar.test
+ tags/
+ foo.test
+ bar.test
+ IntegrationTest.php
+
+The ``IntegrationTest.php`` file should look like this::
+
+ class Project_Tests_IntegrationTest extends Twig_Test_IntegrationTestCase
+ {
+ public function getExtensions()
+ {
+ return array(
+ new Project_Twig_Extension1(),
+ new Project_Twig_Extension2(),
+ );
+ }
+
+ public function getFixturesDir()
+ {
+ return dirname(__FILE__).'/Fixtures/';
+ }
+ }
+
+Fixtures examples can be found within the Twig repository
+`tests/Twig/Fixtures`_ directory.
+
+Node Tests
+~~~~~~~~~~
+
+Testing the node visitors can be complex, so extend your test cases from
+``Twig_Test_NodeTestCase``. Examples can be found in the Twig repository
+`tests/Twig/Node`_ directory.
+
+.. _`rot13`: http://www.php.net/manual/en/function.str-rot13.php
+.. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Fixtures
+.. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Node
diff --git a/src/composer/vendor/twig/twig/doc/advanced_legacy.rst b/src/composer/vendor/twig/twig/doc/advanced_legacy.rst
new file mode 100644
index 00000000..2ef6bfde
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/advanced_legacy.rst
@@ -0,0 +1,887 @@
+Extending Twig
+==============
+
+.. caution::
+
+ This section describes how to extends Twig for versions **older than
+ 1.12**. If you are using a newer version, read the :doc:`newer`
+ chapter instead.
+
+Twig can be extended in many ways; you can add extra tags, filters, tests,
+operators, global variables, and functions. You can even extend the parser
+itself with node visitors.
+
+.. note::
+
+ The first section of this chapter describes how to extend Twig easily. If
+ you want to reuse your changes in different projects or if you want to
+ share them with others, you should then create an extension as described
+ in the following section.
+
+.. caution::
+
+ When extending Twig by calling methods on the Twig environment instance,
+ Twig won't be able to recompile your templates when the PHP code is
+ updated. To see your changes in real-time, either disable template caching
+ or package your code into an extension (see the next section of this
+ chapter).
+
+Before extending Twig, you must understand the differences between all the
+different possible extension points and when to use them.
+
+First, remember that Twig has two main language constructs:
+
+* ``{{ }}``: used to print the result of an expression evaluation;
+
+* ``{% %}``: used to execute statements.
+
+To understand why Twig exposes so many extension points, let's see how to
+implement a *Lorem ipsum* generator (it needs to know the number of words to
+generate).
+
+You can use a ``lipsum`` *tag*:
+
+.. code-block:: jinja
+
+ {% lipsum 40 %}
+
+That works, but using a tag for ``lipsum`` is not a good idea for at least
+three main reasons:
+
+* ``lipsum`` is not a language construct;
+* The tag outputs something;
+* The tag is not flexible as you cannot use it in an expression:
+
+ .. code-block:: jinja
+
+ {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }}
+
+In fact, you rarely need to create tags; and that's good news because tags are
+the most complex extension point of Twig.
+
+Now, let's use a ``lipsum`` *filter*:
+
+.. code-block:: jinja
+
+ {{ 40|lipsum }}
+
+Again, it works, but it looks weird. A filter transforms the passed value to
+something else but here we use the value to indicate the number of words to
+generate (so, ``40`` is an argument of the filter, not the value we want to
+transform).
+
+Next, let's use a ``lipsum`` *function*:
+
+.. code-block:: jinja
+
+ {{ lipsum(40) }}
+
+Here we go. For this specific example, the creation of a function is the
+extension point to use. And you can use it anywhere an expression is accepted:
+
+.. code-block:: jinja
+
+ {{ 'some text' ~ ipsum(40) ~ 'some more text' }}
+
+ {% set ipsum = ipsum(40) %}
+
+Last but not the least, you can also use a *global* object with a method able
+to generate lorem ipsum text:
+
+.. code-block:: jinja
+
+ {{ text.lipsum(40) }}
+
+As a rule of thumb, use functions for frequently used features and global
+objects for everything else.
+
+Keep in mind the following when you want to extend Twig:
+
+========== ========================== ========== =========================
+What? Implementation difficulty? How often? When?
+========== ========================== ========== =========================
+*macro* trivial frequent Content generation
+*global* trivial frequent Helper object
+*function* trivial frequent Content generation
+*filter* trivial frequent Value transformation
+*tag* complex rare DSL language construct
+*test* trivial rare Boolean decision
+*operator* trivial rare Values transformation
+========== ========================== ========== =========================
+
+Globals
+-------
+
+A global variable is like any other template variable, except that it's
+available in all templates and macros::
+
+ $twig = new Twig_Environment($loader);
+ $twig->addGlobal('text', new Text());
+
+You can then use the ``text`` variable anywhere in a template:
+
+.. code-block:: jinja
+
+ {{ text.lipsum(40) }}
+
+Filters
+-------
+
+A filter is a regular PHP function or an object method that takes the left
+side of the filter (before the pipe ``|``) as first argument and the extra
+arguments passed to the filter (within parentheses ``()``) as extra arguments.
+
+Defining a filter is as easy as associating the filter name with a PHP
+callable. For instance, let's say you have the following code in a template:
+
+.. code-block:: jinja
+
+ {{ 'TWIG'|lower }}
+
+When compiling this template to PHP, Twig looks for the PHP callable
+associated with the ``lower`` filter. The ``lower`` filter is a built-in Twig
+filter, and it is simply mapped to the PHP ``strtolower()`` function. After
+compilation, the generated PHP code is roughly equivalent to:
+
+.. code-block:: html+php
+
+
+
+As you can see, the ``'TWIG'`` string is passed as a first argument to the PHP
+function.
+
+A filter can also take extra arguments like in the following example:
+
+.. code-block:: jinja
+
+ {{ now|date('d/m/Y') }}
+
+In this case, the extra arguments are passed to the function after the main
+argument, and the compiled code is equivalent to:
+
+.. code-block:: html+php
+
+
+
+Let's see how to create a new filter.
+
+In this section, we will create a ``rot13`` filter, which should return the
+`rot13`_ transformation of a string. Here is an example of its usage and the
+expected output:
+
+.. code-block:: jinja
+
+ {{ "Twig"|rot13 }}
+
+ {# should displays Gjvt #}
+
+Adding a filter is as simple as calling the ``addFilter()`` method on the
+``Twig_Environment`` instance::
+
+ $twig = new Twig_Environment($loader);
+ $twig->addFilter('rot13', new Twig_Filter_Function('str_rot13'));
+
+The second argument of ``addFilter()`` is an instance of ``Twig_Filter``.
+Here, we use ``Twig_Filter_Function`` as the filter is a PHP function. The
+first argument passed to the ``Twig_Filter_Function`` constructor is the name
+of the PHP function to call, here ``str_rot13``, a native PHP function.
+
+Let's say I now want to be able to add a prefix before the converted string:
+
+.. code-block:: jinja
+
+ {{ "Twig"|rot13('prefix_') }}
+
+ {# should displays prefix_Gjvt #}
+
+As the PHP ``str_rot13()`` function does not support this requirement, let's
+create a new PHP function::
+
+ function project_compute_rot13($string, $prefix = '')
+ {
+ return $prefix.str_rot13($string);
+ }
+
+As you can see, the ``prefix`` argument of the filter is passed as an extra
+argument to the ``project_compute_rot13()`` function.
+
+Adding this filter is as easy as before::
+
+ $twig->addFilter('rot13', new Twig_Filter_Function('project_compute_rot13'));
+
+For better encapsulation, a filter can also be defined as a static method of a
+class. The ``Twig_Filter_Function`` class can also be used to register such
+static methods as filters::
+
+ $twig->addFilter('rot13', new Twig_Filter_Function('SomeClass::rot13Filter'));
+
+.. tip::
+
+ In an extension, you can also define a filter as a static method of the
+ extension class.
+
+Environment aware Filters
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``Twig_Filter`` classes take options as their last argument. For instance,
+if you want access to the current environment instance in your filter, set the
+``needs_environment`` option to ``true``::
+
+ $filter = new Twig_Filter_Function('str_rot13', array('needs_environment' => true));
+
+Twig will then pass the current environment as the first argument to the
+filter call::
+
+ function twig_compute_rot13(Twig_Environment $env, $string)
+ {
+ // get the current charset for instance
+ $charset = $env->getCharset();
+
+ return str_rot13($string);
+ }
+
+Automatic Escaping
+~~~~~~~~~~~~~~~~~~
+
+If automatic escaping is enabled, the output of the filter may be escaped
+before printing. If your filter acts as an escaper (or explicitly outputs HTML
+or JavaScript code), you will want the raw output to be printed. In such a
+case, set the ``is_safe`` option::
+
+ $filter = new Twig_Filter_Function('nl2br', array('is_safe' => array('html')));
+
+Some filters may need to work on input that is already escaped or safe, for
+example when adding (safe) HTML tags to originally unsafe output. In such a
+case, set the ``pre_escape`` option to escape the input data before it is run
+through your filter::
+
+ $filter = new Twig_Filter_Function('somefilter', array('pre_escape' => 'html', 'is_safe' => array('html')));
+
+Dynamic Filters
+~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.5
+ Dynamic filters support was added in Twig 1.5.
+
+A filter name containing the special ``*`` character is a dynamic filter as
+the ``*`` can be any string::
+
+ $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path'));
+
+ function twig_path($name, $arguments)
+ {
+ // ...
+ }
+
+The following filters will be matched by the above defined dynamic filter:
+
+* ``product_path``
+* ``category_path``
+
+A dynamic filter can define more than one dynamic parts::
+
+ $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path'));
+
+ function twig_path($name, $suffix, $arguments)
+ {
+ // ...
+ }
+
+The filter will receive all dynamic part values before the normal filters
+arguments. For instance, a call to ``'foo'|a_path_b()`` will result in the
+following PHP call: ``twig_path('a', 'b', 'foo')``.
+
+Functions
+---------
+
+A function is a regular PHP function or an object method that can be called from
+templates.
+
+.. code-block:: jinja
+
+ {{ constant("DATE_W3C") }}
+
+When compiling this template to PHP, Twig looks for the PHP callable
+associated with the ``constant`` function. The ``constant`` function is a built-in Twig
+function, and it is simply mapped to the PHP ``constant()`` function. After
+compilation, the generated PHP code is roughly equivalent to:
+
+.. code-block:: html+php
+
+
+
+Adding a function is similar to adding a filter. This can be done by calling the
+``addFunction()`` method on the ``Twig_Environment`` instance::
+
+ $twig = new Twig_Environment($loader);
+ $twig->addFunction('functionName', new Twig_Function_Function('someFunction'));
+
+You can also expose extension methods as functions in your templates::
+
+ // $this is an object that implements Twig_ExtensionInterface.
+ $twig = new Twig_Environment($loader);
+ $twig->addFunction('otherFunction', new Twig_Function_Method($this, 'someMethod'));
+
+Functions also support ``needs_environment`` and ``is_safe`` parameters.
+
+Dynamic Functions
+~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.5
+ Dynamic functions support was added in Twig 1.5.
+
+A function name containing the special ``*`` character is a dynamic function
+as the ``*`` can be any string::
+
+ $twig->addFunction('*_path', new Twig_Function_Function('twig_path'));
+
+ function twig_path($name, $arguments)
+ {
+ // ...
+ }
+
+The following functions will be matched by the above defined dynamic function:
+
+* ``product_path``
+* ``category_path``
+
+A dynamic function can define more than one dynamic parts::
+
+ $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path'));
+
+ function twig_path($name, $suffix, $arguments)
+ {
+ // ...
+ }
+
+The function will receive all dynamic part values before the normal functions
+arguments. For instance, a call to ``a_path_b('foo')`` will result in the
+following PHP call: ``twig_path('a', 'b', 'foo')``.
+
+Tags
+----
+
+One of the most exciting feature of a template engine like Twig is the
+possibility to define new language constructs. This is also the most complex
+feature as you need to understand how Twig's internals work.
+
+Let's create a simple ``set`` tag that allows the definition of simple
+variables from within a template. The tag can be used like follows:
+
+.. code-block:: jinja
+
+ {% set name = "value" %}
+
+ {{ name }}
+
+ {# should output value #}
+
+.. note::
+
+ The ``set`` tag is part of the Core extension and as such is always
+ available. The built-in version is slightly more powerful and supports
+ multiple assignments by default (cf. the template designers chapter for
+ more information).
+
+Three steps are needed to define a new tag:
+
+* Defining a Token Parser class (responsible for parsing the template code);
+
+* Defining a Node class (responsible for converting the parsed code to PHP);
+
+* Registering the tag.
+
+Registering a new tag
+~~~~~~~~~~~~~~~~~~~~~
+
+Adding a tag is as simple as calling the ``addTokenParser`` method on the
+``Twig_Environment`` instance::
+
+ $twig = new Twig_Environment($loader);
+ $twig->addTokenParser(new Project_Set_TokenParser());
+
+Defining a Token Parser
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Now, let's see the actual code of this class::
+
+ class Project_Set_TokenParser extends Twig_TokenParser
+ {
+ public function parse(Twig_Token $token)
+ {
+ $lineno = $token->getLine();
+ $name = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
+ $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, '=');
+ $value = $this->parser->getExpressionParser()->parseExpression();
+
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+ return new Project_Set_Node($name, $value, $lineno, $this->getTag());
+ }
+
+ public function getTag()
+ {
+ return 'set';
+ }
+ }
+
+The ``getTag()`` method must return the tag we want to parse, here ``set``.
+
+The ``parse()`` method is invoked whenever the parser encounters a ``set``
+tag. It should return a ``Twig_Node`` instance that represents the node (the
+``Project_Set_Node`` calls creating is explained in the next section).
+
+The parsing process is simplified thanks to a bunch of methods you can call
+from the token stream (``$this->parser->getStream()``):
+
+* ``getCurrent()``: Gets the current token in the stream.
+
+* ``next()``: Moves to the next token in the stream, *but returns the old one*.
+
+* ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether
+ the current token is of a particular type or value (or both). The value may be an
+ array of several possible values.
+
+* ``expect($type[, $value[, $message]])``: If the current token isn't of the given
+ type/value a syntax error is thrown. Otherwise, if the type and value are correct,
+ the token is returned and the stream moves to the next token.
+
+* ``look()``: Looks a the next token without consuming it.
+
+Parsing expressions is done by calling the ``parseExpression()`` like we did for
+the ``set`` tag.
+
+.. tip::
+
+ Reading the existing ``TokenParser`` classes is the best way to learn all
+ the nitty-gritty details of the parsing process.
+
+Defining a Node
+~~~~~~~~~~~~~~~
+
+The ``Project_Set_Node`` class itself is rather simple::
+
+ class Project_Set_Node extends Twig_Node
+ {
+ public function __construct($name, Twig_Node_Expression $value, $lineno, $tag = null)
+ {
+ parent::__construct(array('value' => $value), array('name' => $name), $lineno, $tag);
+ }
+
+ public function compile(Twig_Compiler $compiler)
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->write('$context[\''.$this->getAttribute('name').'\'] = ')
+ ->subcompile($this->getNode('value'))
+ ->raw(";\n")
+ ;
+ }
+ }
+
+The compiler implements a fluid interface and provides methods that helps the
+developer generate beautiful and readable PHP code:
+
+* ``subcompile()``: Compiles a node.
+
+* ``raw()``: Writes the given string as is.
+
+* ``write()``: Writes the given string by adding indentation at the beginning
+ of each line.
+
+* ``string()``: Writes a quoted string.
+
+* ``repr()``: Writes a PHP representation of a given value (see
+ ``Twig_Node_For`` for a usage example).
+
+* ``addDebugInfo()``: Adds the line of the original template file related to
+ the current node as a comment.
+
+* ``indent()``: Indents the generated code (see ``Twig_Node_Block`` for a
+ usage example).
+
+* ``outdent()``: Outdents the generated code (see ``Twig_Node_Block`` for a
+ usage example).
+
+.. _creating_extensions:
+
+Creating an Extension
+---------------------
+
+The main motivation for writing an extension is to move often used code into a
+reusable class like adding support for internationalization. An extension can
+define tags, filters, tests, operators, global variables, functions, and node
+visitors.
+
+Creating an extension also makes for a better separation of code that is
+executed at compilation time and code needed at runtime. As such, it makes
+your code faster.
+
+Most of the time, it is useful to create a single extension for your project,
+to host all the specific tags and filters you want to add to Twig.
+
+.. tip::
+
+ When packaging your code into an extension, Twig is smart enough to
+ recompile your templates whenever you make a change to it (when the
+ ``auto_reload`` is enabled).
+
+.. note::
+
+ Before writing your own extensions, have a look at the Twig official
+ extension repository: http://github.com/twigphp/Twig-extensions.
+
+An extension is a class that implements the following interface::
+
+ interface Twig_ExtensionInterface
+ {
+ /**
+ * Initializes the runtime environment.
+ *
+ * This is where you can load some file that contains filter functions for instance.
+ *
+ * @param Twig_Environment $environment The current Twig_Environment instance
+ */
+ function initRuntime(Twig_Environment $environment);
+
+ /**
+ * Returns the token parser instances to add to the existing list.
+ *
+ * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
+ */
+ function getTokenParsers();
+
+ /**
+ * Returns the node visitor instances to add to the existing list.
+ *
+ * @return array An array of Twig_NodeVisitorInterface instances
+ */
+ function getNodeVisitors();
+
+ /**
+ * Returns a list of filters to add to the existing list.
+ *
+ * @return array An array of filters
+ */
+ function getFilters();
+
+ /**
+ * Returns a list of tests to add to the existing list.
+ *
+ * @return array An array of tests
+ */
+ function getTests();
+
+ /**
+ * Returns a list of functions to add to the existing list.
+ *
+ * @return array An array of functions
+ */
+ function getFunctions();
+
+ /**
+ * Returns a list of operators to add to the existing list.
+ *
+ * @return array An array of operators
+ */
+ function getOperators();
+
+ /**
+ * Returns a list of global variables to add to the existing list.
+ *
+ * @return array An array of global variables
+ */
+ function getGlobals();
+
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ */
+ function getName();
+ }
+
+To keep your extension class clean and lean, it can inherit from the built-in
+``Twig_Extension`` class instead of implementing the whole interface. That
+way, you just need to implement the ``getName()`` method as the
+``Twig_Extension`` provides empty implementations for all other methods.
+
+The ``getName()`` method must return a unique identifier for your extension.
+
+Now, with this information in mind, let's create the most basic extension
+possible::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getName()
+ {
+ return 'project';
+ }
+ }
+
+.. note::
+
+ Of course, this extension does nothing for now. We will customize it in
+ the next sections.
+
+Twig does not care where you save your extension on the filesystem, as all
+extensions must be registered explicitly to be available in your templates.
+
+You can register an extension by using the ``addExtension()`` method on your
+main ``Environment`` object::
+
+ $twig = new Twig_Environment($loader);
+ $twig->addExtension(new Project_Twig_Extension());
+
+Of course, you need to first load the extension file by either using
+``require_once()`` or by using an autoloader (see `spl_autoload_register()`_).
+
+.. tip::
+
+ The bundled extensions are great examples of how extensions work.
+
+Globals
+~~~~~~~
+
+Global variables can be registered in an extension via the ``getGlobals()``
+method::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getGlobals()
+ {
+ return array(
+ 'text' => new Text(),
+ );
+ }
+
+ // ...
+ }
+
+Functions
+~~~~~~~~~
+
+Functions can be registered in an extension via the ``getFunctions()``
+method::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getFunctions()
+ {
+ return array(
+ 'lipsum' => new Twig_Function_Function('generate_lipsum'),
+ );
+ }
+
+ // ...
+ }
+
+Filters
+~~~~~~~
+
+To add a filter to an extension, you need to override the ``getFilters()``
+method. This method must return an array of filters to add to the Twig
+environment::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getFilters()
+ {
+ return array(
+ 'rot13' => new Twig_Filter_Function('str_rot13'),
+ );
+ }
+
+ // ...
+ }
+
+As you can see in the above code, the ``getFilters()`` method returns an array
+where keys are the name of the filters (``rot13``) and the values the
+definition of the filter (``new Twig_Filter_Function('str_rot13')``).
+
+As seen in the previous chapter, you can also define filters as static methods
+on the extension class::
+
+$twig->addFilter('rot13', new Twig_Filter_Function('Project_Twig_Extension::rot13Filter'));
+
+You can also use ``Twig_Filter_Method`` instead of ``Twig_Filter_Function``
+when defining a filter to use a method::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getFilters()
+ {
+ return array(
+ 'rot13' => new Twig_Filter_Method($this, 'rot13Filter'),
+ );
+ }
+
+ public function rot13Filter($string)
+ {
+ return str_rot13($string);
+ }
+
+ // ...
+ }
+
+The first argument of the ``Twig_Filter_Method`` constructor is always
+``$this``, the current extension object. The second one is the name of the
+method to call.
+
+Using methods for filters is a great way to package your filter without
+polluting the global namespace. This also gives the developer more flexibility
+at the cost of a small overhead.
+
+Overriding default Filters
+..........................
+
+If some default core filters do not suit your needs, you can easily override
+them by creating your own extension. Just use the same names as the one you
+want to override::
+
+ class MyCoreExtension extends Twig_Extension
+ {
+ public function getFilters()
+ {
+ return array(
+ 'date' => new Twig_Filter_Method($this, 'dateFilter'),
+ // ...
+ );
+ }
+
+ public function dateFilter($timestamp, $format = 'F j, Y H:i')
+ {
+ return '...'.twig_date_format_filter($timestamp, $format);
+ }
+
+ public function getName()
+ {
+ return 'project';
+ }
+ }
+
+Here, we override the ``date`` filter with a custom one. Using this extension
+is as simple as registering the ``MyCoreExtension`` extension by calling the
+``addExtension()`` method on the environment instance::
+
+ $twig = new Twig_Environment($loader);
+ $twig->addExtension(new MyCoreExtension());
+
+Tags
+~~~~
+
+Adding a tag in an extension can be done by overriding the
+``getTokenParsers()`` method. This method must return an array of tags to add
+to the Twig environment::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getTokenParsers()
+ {
+ return array(new Project_Set_TokenParser());
+ }
+
+ // ...
+ }
+
+In the above code, we have added a single new tag, defined by the
+``Project_Set_TokenParser`` class. The ``Project_Set_TokenParser`` class is
+responsible for parsing the tag and compiling it to PHP.
+
+Operators
+~~~~~~~~~
+
+The ``getOperators()`` methods allows to add new operators. Here is how to add
+``!``, ``||``, and ``&&`` operators::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getOperators()
+ {
+ return array(
+ array(
+ '!' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'),
+ ),
+ array(
+ '||' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ '&&' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+ ),
+ );
+ }
+
+ // ...
+ }
+
+Tests
+~~~~~
+
+The ``getTests()`` methods allows to add new test functions::
+
+ class Project_Twig_Extension extends Twig_Extension
+ {
+ public function getTests()
+ {
+ return array(
+ 'even' => new Twig_Test_Function('twig_test_even'),
+ );
+ }
+
+ // ...
+ }
+
+Testing an Extension
+--------------------
+
+.. versionadded:: 1.10
+ Support for functional tests was added in Twig 1.10.
+
+Functional Tests
+~~~~~~~~~~~~~~~~
+
+You can create functional tests for extensions simply by creating the
+following file structure in your test directory::
+
+ Fixtures/
+ filters/
+ foo.test
+ bar.test
+ functions/
+ foo.test
+ bar.test
+ tags/
+ foo.test
+ bar.test
+ IntegrationTest.php
+
+The ``IntegrationTest.php`` file should look like this::
+
+ class Project_Tests_IntegrationTest extends Twig_Test_IntegrationTestCase
+ {
+ public function getExtensions()
+ {
+ return array(
+ new Project_Twig_Extension1(),
+ new Project_Twig_Extension2(),
+ );
+ }
+
+ public function getFixturesDir()
+ {
+ return dirname(__FILE__).'/Fixtures/';
+ }
+ }
+
+Fixtures examples can be found within the Twig repository
+`tests/Twig/Fixtures`_ directory.
+
+Node Tests
+~~~~~~~~~~
+
+Testing the node visitors can be complex, so extend your test cases from
+``Twig_Test_NodeTestCase``. Examples can be found in the Twig repository
+`tests/Twig/Node`_ directory.
+
+.. _`spl_autoload_register()`: http://www.php.net/spl_autoload_register
+.. _`rot13`: http://www.php.net/manual/en/function.str-rot13.php
+.. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Fixtures
+.. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/master/test/Twig/Tests/Node
diff --git a/src/composer/vendor/twig/twig/doc/api.rst b/src/composer/vendor/twig/twig/doc/api.rst
new file mode 100644
index 00000000..f367db07
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/api.rst
@@ -0,0 +1,552 @@
+Twig for Developers
+===================
+
+This chapter describes the API to Twig and not the template language. It will
+be most useful as reference to those implementing the template interface to
+the application and not those who are creating Twig templates.
+
+Basics
+------
+
+Twig uses a central object called the **environment** (of class
+``Twig_Environment``). Instances of this class are used to store the
+configuration and extensions, and are used to load templates from the file
+system or other locations.
+
+Most applications will create one ``Twig_Environment`` object on application
+initialization and use that to load templates. In some cases it's however
+useful to have multiple environments side by side, if different configurations
+are in use.
+
+The simplest way to configure Twig to load templates for your application
+looks roughly like this::
+
+ require_once '/path/to/lib/Twig/Autoloader.php';
+ Twig_Autoloader::register();
+
+ $loader = new Twig_Loader_Filesystem('/path/to/templates');
+ $twig = new Twig_Environment($loader, array(
+ 'cache' => '/path/to/compilation_cache',
+ ));
+
+This will create a template environment with the default settings and a loader
+that looks up the templates in the ``/path/to/templates/`` folder. Different
+loaders are available and you can also write your own if you want to load
+templates from a database or other resources.
+
+.. note::
+
+ Notice that the second argument of the environment is an array of options.
+ The ``cache`` option is a compilation cache directory, where Twig caches
+ the compiled templates to avoid the parsing phase for sub-sequent
+ requests. It is very different from the cache you might want to add for
+ the evaluated templates. For such a need, you can use any available PHP
+ cache library.
+
+To load a template from this environment you just have to call the
+``loadTemplate()`` method which then returns a ``Twig_Template`` instance::
+
+ $template = $twig->loadTemplate('index.html');
+
+To render the template with some variables, call the ``render()`` method::
+
+ echo $template->render(array('the' => 'variables', 'go' => 'here'));
+
+.. note::
+
+ The ``display()`` method is a shortcut to output the template directly.
+
+You can also load and render the template in one fell swoop::
+
+ echo $twig->render('index.html', array('the' => 'variables', 'go' => 'here'));
+
+.. _environment_options:
+
+Environment Options
+-------------------
+
+When creating a new ``Twig_Environment`` instance, you can pass an array of
+options as the constructor second argument::
+
+ $twig = new Twig_Environment($loader, array('debug' => true));
+
+The following options are available:
+
+* ``debug`` *boolean*
+
+ When set to ``true``, the generated templates have a
+ ``__toString()`` method that you can use to display the generated nodes
+ (default to ``false``).
+
+* ``charset`` *string (default to ``utf-8``)*
+
+ The charset used by the templates.
+
+* ``base_template_class`` *string (default to ``Twig_Template``)*
+
+ The base template class to use for generated
+ templates.
+
+* ``cache`` *string|false*
+
+ An absolute path where to store the compiled templates, or
+ ``false`` to disable caching (which is the default).
+
+* ``auto_reload`` *boolean*
+
+ When developing with Twig, it's useful to recompile the
+ template whenever the source code changes. If you don't provide a value for
+ the ``auto_reload`` option, it will be determined automatically based on the
+ ``debug`` value.
+
+* ``strict_variables`` *boolean*
+
+ If set to ``false``, Twig will silently ignore invalid
+ variables (variables and or attributes/methods that do not exist) and
+ replace them with a ``null`` value. When set to ``true``, Twig throws an
+ exception instead (default to ``false``).
+
+* ``autoescape`` *string|boolean*
+
+ If set to ``true``, HTML auto-escaping will be enabled by
+ default for all templates (default to ``true``).
+
+ As of Twig 1.8, you can set the escaping strategy to use (``html``, ``js``,
+ ``false`` to disable).
+
+ As of Twig 1.9, you can set the escaping strategy to use (``css``, ``url``,
+ ``html_attr``, or a PHP callback that takes the template "filename" and must
+ return the escaping strategy to use -- the callback cannot be a function name
+ to avoid collision with built-in escaping strategies).
+
+ As of Twig 1.17, the ``filename`` escaping strategy determines the escaping
+ strategy to use for a template based on the template filename extension (this
+ strategy does not incur any overhead at runtime as auto-escaping is done at
+ compilation time.)
+
+* ``optimizations`` *integer*
+
+ A flag that indicates which optimizations to apply
+ (default to ``-1`` -- all optimizations are enabled; set it to ``0`` to
+ disable).
+
+Loaders
+-------
+
+Loaders are responsible for loading templates from a resource such as the file
+system.
+
+Compilation Cache
+~~~~~~~~~~~~~~~~~
+
+All template loaders can cache the compiled templates on the filesystem for
+future reuse. It speeds up Twig a lot as templates are only compiled once; and
+the performance boost is even larger if you use a PHP accelerator such as APC.
+See the ``cache`` and ``auto_reload`` options of ``Twig_Environment`` above
+for more information.
+
+Built-in Loaders
+~~~~~~~~~~~~~~~~
+
+Here is a list of the built-in loaders Twig provides:
+
+``Twig_Loader_Filesystem``
+..........................
+
+.. versionadded:: 1.10
+ The ``prependPath()`` and support for namespaces were added in Twig 1.10.
+
+``Twig_Loader_Filesystem`` loads templates from the file system. This loader
+can find templates in folders on the file system and is the preferred way to
+load them::
+
+ $loader = new Twig_Loader_Filesystem($templateDir);
+
+It can also look for templates in an array of directories::
+
+ $loader = new Twig_Loader_Filesystem(array($templateDir1, $templateDir2));
+
+With such a configuration, Twig will first look for templates in
+``$templateDir1`` and if they do not exist, it will fallback to look for them
+in the ``$templateDir2``.
+
+You can add or prepend paths via the ``addPath()`` and ``prependPath()``
+methods::
+
+ $loader->addPath($templateDir3);
+ $loader->prependPath($templateDir4);
+
+The filesystem loader also supports namespaced templates. This allows to group
+your templates under different namespaces which have their own template paths.
+
+When using the ``setPaths()``, ``addPath()``, and ``prependPath()`` methods,
+specify the namespace as the second argument (when not specified, these
+methods act on the "main" namespace)::
+
+ $loader->addPath($templateDir, 'admin');
+
+Namespaced templates can be accessed via the special
+``@namespace_name/template_path`` notation::
+
+ $twig->render('@admin/index.html', array());
+
+``Twig_Loader_Array``
+.....................
+
+``Twig_Loader_Array`` loads a template from a PHP array. It's passed an array
+of strings bound to template names::
+
+ $loader = new Twig_Loader_Array(array(
+ 'index.html' => 'Hello {{ name }}!',
+ ));
+ $twig = new Twig_Environment($loader);
+
+ echo $twig->render('index.html', array('name' => 'Fabien'));
+
+This loader is very useful for unit testing. It can also be used for small
+projects where storing all templates in a single PHP file might make sense.
+
+.. tip::
+
+ When using the ``Array`` or ``String`` loaders with a cache mechanism, you
+ should know that a new cache key is generated each time a template content
+ "changes" (the cache key being the source code of the template). If you
+ don't want to see your cache grows out of control, you need to take care
+ of clearing the old cache file by yourself.
+
+``Twig_Loader_Chain``
+.....................
+
+``Twig_Loader_Chain`` delegates the loading of templates to other loaders::
+
+ $loader1 = new Twig_Loader_Array(array(
+ 'base.html' => '{% block content %}{% endblock %}',
+ ));
+ $loader2 = new Twig_Loader_Array(array(
+ 'index.html' => '{% extends "base.html" %}{% block content %}Hello {{ name }}{% endblock %}',
+ 'base.html' => 'Will never be loaded',
+ ));
+
+ $loader = new Twig_Loader_Chain(array($loader1, $loader2));
+
+ $twig = new Twig_Environment($loader);
+
+When looking for a template, Twig will try each loader in turn and it will
+return as soon as the template is found. When rendering the ``index.html``
+template from the above example, Twig will load it with ``$loader2`` but the
+``base.html`` template will be loaded from ``$loader1``.
+
+``Twig_Loader_Chain`` accepts any loader that implements
+``Twig_LoaderInterface``.
+
+.. note::
+
+ You can also add loaders via the ``addLoader()`` method.
+
+Create your own Loader
+~~~~~~~~~~~~~~~~~~~~~~
+
+All loaders implement the ``Twig_LoaderInterface``::
+
+ interface Twig_LoaderInterface
+ {
+ /**
+ * Gets the source code of a template, given its name.
+ *
+ * @param string $name string The name of the template to load
+ *
+ * @return string The template source code
+ */
+ function getSource($name);
+
+ /**
+ * Gets the cache key to use for the cache for a given template name.
+ *
+ * @param string $name string The name of the template to load
+ *
+ * @return string The cache key
+ */
+ function getCacheKey($name);
+
+ /**
+ * Returns true if the template is still fresh.
+ *
+ * @param string $name The template name
+ * @param timestamp $time The last modification time of the cached template
+ */
+ function isFresh($name, $time);
+ }
+
+The ``isFresh()`` method must return ``true`` if the current cached template
+is still fresh, given the last modification time, or ``false`` otherwise.
+
+.. tip::
+
+ As of Twig 1.11.0, you can also implement ``Twig_ExistsLoaderInterface``
+ to make your loader faster when used with the chain loader.
+
+Using Extensions
+----------------
+
+Twig extensions are packages that add new features to Twig. Using an
+extension is as simple as using the ``addExtension()`` method::
+
+ $twig->addExtension(new Twig_Extension_Sandbox());
+
+Twig comes bundled with the following extensions:
+
+* *Twig_Extension_Core*: Defines all the core features of Twig.
+
+* *Twig_Extension_Escaper*: Adds automatic output-escaping and the possibility
+ to escape/unescape blocks of code.
+
+* *Twig_Extension_Sandbox*: Adds a sandbox mode to the default Twig
+ environment, making it safe to evaluate untrusted code.
+
+* *Twig_Extension_Profiler*: Enabled the built-in Twig profiler (as of Twig
+ 1.18).
+
+* *Twig_Extension_Optimizer*: Optimizes the node tree before compilation.
+
+The core, escaper, and optimizer extensions do not need to be added to the
+Twig environment, as they are registered by default.
+
+Built-in Extensions
+-------------------
+
+This section describes the features added by the built-in extensions.
+
+.. tip::
+
+ Read the chapter about extending Twig to learn how to create your own
+ extensions.
+
+Core Extension
+~~~~~~~~~~~~~~
+
+The ``core`` extension defines all the core features of Twig:
+
+* :doc:`Tags `;
+* :doc:`Filters `;
+* :doc:`Functions `;
+* :doc:`Tests `.
+
+Escaper Extension
+~~~~~~~~~~~~~~~~~
+
+The ``escaper`` extension adds automatic output escaping to Twig. It defines a
+tag, ``autoescape``, and a filter, ``raw``.
+
+When creating the escaper extension, you can switch on or off the global
+output escaping strategy::
+
+ $escaper = new Twig_Extension_Escaper('html');
+ $twig->addExtension($escaper);
+
+If set to ``html``, all variables in templates are escaped (using the ``html``
+escaping strategy), except those using the ``raw`` filter:
+
+.. code-block:: jinja
+
+ {{ article.to_html|raw }}
+
+You can also change the escaping mode locally by using the ``autoescape`` tag
+(see the :doc:`autoescape` doc for the syntax used before
+Twig 1.8):
+
+.. code-block:: jinja
+
+ {% autoescape 'html' %}
+ {{ var }}
+ {{ var|raw }} {# var won't be escaped #}
+ {{ var|escape }} {# var won't be double-escaped #}
+ {% endautoescape %}
+
+.. warning::
+
+ The ``autoescape`` tag has no effect on included files.
+
+The escaping rules are implemented as follows:
+
+* Literals (integers, booleans, arrays, ...) used in the template directly as
+ variables or filter arguments are never automatically escaped:
+
+ .. code-block:: jinja
+
+ {{ "Twig " }} {# won't be escaped #}
+
+ {% set text = "Twig " %}
+ {{ text }} {# will be escaped #}
+
+* Expressions which the result is always a literal or a variable marked safe
+ are never automatically escaped:
+
+ .. code-block:: jinja
+
+ {{ foo ? "Twig " : " Twig" }} {# won't be escaped #}
+
+ {% set text = "Twig " %}
+ {{ foo ? text : " Twig" }} {# will be escaped #}
+
+ {% set text = "Twig " %}
+ {{ foo ? text|raw : " Twig" }} {# won't be escaped #}
+
+ {% set text = "Twig " %}
+ {{ foo ? text|escape : " Twig" }} {# the result of the expression won't be escaped #}
+
+* Escaping is applied before printing, after any other filter is applied:
+
+ .. code-block:: jinja
+
+ {{ var|upper }} {# is equivalent to {{ var|upper|escape }} #}
+
+* The `raw` filter should only be used at the end of the filter chain:
+
+ .. code-block:: jinja
+
+ {{ var|raw|upper }} {# will be escaped #}
+
+ {{ var|upper|raw }} {# won't be escaped #}
+
+* Automatic escaping is not applied if the last filter in the chain is marked
+ safe for the current context (e.g. ``html`` or ``js``). ``escape`` and
+ ``escape('html')`` are marked safe for HTML, ``escape('js')`` is marked
+ safe for JavaScript, ``raw`` is marked safe for everything.
+
+ .. code-block:: jinja
+
+ {% autoescape 'js' %}
+ {{ var|escape('html') }} {# will be escaped for HTML and JavaScript #}
+ {{ var }} {# will be escaped for JavaScript #}
+ {{ var|escape('js') }} {# won't be double-escaped #}
+ {% endautoescape %}
+
+.. note::
+
+ Note that autoescaping has some limitations as escaping is applied on
+ expressions after evaluation. For instance, when working with
+ concatenation, ``{{ foo|raw ~ bar }}`` won't give the expected result as
+ escaping is applied on the result of the concatenation, not on the
+ individual variables (so, the ``raw`` filter won't have any effect here).
+
+Sandbox Extension
+~~~~~~~~~~~~~~~~~
+
+The ``sandbox`` extension can be used to evaluate untrusted code. Access to
+unsafe attributes and methods is prohibited. The sandbox security is managed
+by a policy instance. By default, Twig comes with one policy class:
+``Twig_Sandbox_SecurityPolicy``. This class allows you to white-list some
+tags, filters, properties, and methods::
+
+ $tags = array('if');
+ $filters = array('upper');
+ $methods = array(
+ 'Article' => array('getTitle', 'getBody'),
+ );
+ $properties = array(
+ 'Article' => array('title', 'body'),
+ );
+ $functions = array('range');
+ $policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties, $functions);
+
+With the previous configuration, the security policy will only allow usage of
+the ``if`` tag, and the ``upper`` filter. Moreover, the templates will only be
+able to call the ``getTitle()`` and ``getBody()`` methods on ``Article``
+objects, and the ``title`` and ``body`` public properties. Everything else
+won't be allowed and will generate a ``Twig_Sandbox_SecurityError`` exception.
+
+The policy object is the first argument of the sandbox constructor::
+
+ $sandbox = new Twig_Extension_Sandbox($policy);
+ $twig->addExtension($sandbox);
+
+By default, the sandbox mode is disabled and should be enabled when including
+untrusted template code by using the ``sandbox`` tag:
+
+.. code-block:: jinja
+
+ {% sandbox %}
+ {% include 'user.html' %}
+ {% endsandbox %}
+
+You can sandbox all templates by passing ``true`` as the second argument of
+the extension constructor::
+
+ $sandbox = new Twig_Extension_Sandbox($policy, true);
+
+Profiler Extension
+~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.18
+ The Profile extension was added in Twig 1.18.
+
+The ``profiler`` extension enables a profiler for Twig templates; it should
+only be used on your development machines as it adds some overhead::
+
+ $profile = new Twig_Profiler_Profile();
+ $twig->addExtension(new Twig_Extension_Profiler($profile));
+
+ $dumper = new Twig_Profiler_Dumper_Text();
+ echo $dumper->dump($profile);
+
+A profile contains information about time and memory consumption for template,
+block, and macro executions.
+
+You can also dump the data in a `Blackfire.io `_
+compatible format::
+
+ $dumper = new Twig_Profiler_Dumper_Blackfire();
+ file_put_contents('/path/to/profile.prof', $dumper->dump($profile));
+
+Upload the profile to visualize it (create a `free account
+`_ first):
+
+.. code-block:: sh
+
+ blackfire --slot=7 upload /path/to/profile.prof
+
+Optimizer Extension
+~~~~~~~~~~~~~~~~~~~
+
+The ``optimizer`` extension optimizes the node tree before compilation::
+
+ $twig->addExtension(new Twig_Extension_Optimizer());
+
+By default, all optimizations are turned on. You can select the ones you want
+to enable by passing them to the constructor::
+
+ $optimizer = new Twig_Extension_Optimizer(Twig_NodeVisitor_Optimizer::OPTIMIZE_FOR);
+
+ $twig->addExtension($optimizer);
+
+Twig supports the following optimizations:
+
+* ``Twig_NodeVisitor_Optimizer::OPTIMIZE_ALL``, enables all optimizations
+ (this is the default value).
+* ``Twig_NodeVisitor_Optimizer::OPTIMIZE_NONE``, disables all optimizations.
+ This reduces the compilation time, but it can increase the execution time
+ and the consumed memory.
+* ``Twig_NodeVisitor_Optimizer::OPTIMIZE_FOR``, optimizes the ``for`` tag by
+ removing the ``loop`` variable creation whenever possible.
+* ``Twig_NodeVisitor_Optimizer::OPTIMIZE_RAW_FILTER``, removes the ``raw``
+ filter whenever possible.
+* ``Twig_NodeVisitor_Optimizer::OPTIMIZE_VAR_ACCESS``, simplifies the creation
+ and access of variables in the compiled templates whenever possible.
+
+Exceptions
+----------
+
+Twig can throw exceptions:
+
+* ``Twig_Error``: The base exception for all errors.
+
+* ``Twig_Error_Syntax``: Thrown to tell the user that there is a problem with
+ the template syntax.
+
+* ``Twig_Error_Runtime``: Thrown when an error occurs at runtime (when a filter
+ does not exist for instance).
+
+* ``Twig_Error_Loader``: Thrown when an error occurs during template loading.
+
+* ``Twig_Sandbox_SecurityError``: Thrown when an unallowed tag, filter, or
+ method is called in a sandboxed template.
diff --git a/src/composer/vendor/twig/twig/doc/coding_standards.rst b/src/composer/vendor/twig/twig/doc/coding_standards.rst
new file mode 100644
index 00000000..f435df49
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/coding_standards.rst
@@ -0,0 +1,101 @@
+Coding Standards
+================
+
+When writing Twig templates, we recommend you to follow these official coding
+standards:
+
+* Put one (and only one) space after the start of a delimiter (``{{``, ``{%``,
+ and ``{#``) and before the end of a delimiter (``}}``, ``%}``, and ``#}``):
+
+ .. code-block:: jinja
+
+ {{ foo }}
+ {# comment #}
+ {% if foo %}{% endif %}
+
+ When using the whitespace control character, do not put any spaces between
+ it and the delimiter:
+
+ .. code-block:: jinja
+
+ {{- foo -}}
+ {#- comment -#}
+ {%- if foo -%}{%- endif -%}
+
+* Put one (and only one) space before and after the following operators:
+ comparison operators (``==``, ``!=``, ``<``, ``>``, ``>=``, ``<=``), math
+ operators (``+``, ``-``, ``/``, ``*``, ``%``, ``//``, ``**``), logic
+ operators (``not``, ``and``, ``or``), ``~``, ``is``, ``in``, and the ternary
+ operator (``?:``):
+
+ .. code-block:: jinja
+
+ {{ 1 + 2 }}
+ {{ foo ~ bar }}
+ {{ true ? true : false }}
+
+* Put one (and only one) space after the ``:`` sign in hashes and ``,`` in
+ arrays and hashes:
+
+ .. code-block:: jinja
+
+ {{ [1, 2, 3] }}
+ {{ {'foo': 'bar'} }}
+
+* Do not put any spaces after an opening parenthesis and before a closing
+ parenthesis in expressions:
+
+ .. code-block:: jinja
+
+ {{ 1 + (2 * 3) }}
+
+* Do not put any spaces before and after string delimiters:
+
+ .. code-block:: jinja
+
+ {{ 'foo' }}
+ {{ "foo" }}
+
+* Do not put any spaces before and after the following operators: ``|``,
+ ``.``, ``..``, ``[]``:
+
+ .. code-block:: jinja
+
+ {{ foo|upper|lower }}
+ {{ user.name }}
+ {{ user[name] }}
+ {% for i in 1..12 %}{% endfor %}
+
+* Do not put any spaces before and after the parenthesis used for filter and
+ function calls:
+
+ .. code-block:: jinja
+
+ {{ foo|default('foo') }}
+ {{ range(1..10) }}
+
+* Do not put any spaces before and after the opening and the closing of arrays
+ and hashes:
+
+ .. code-block:: jinja
+
+ {{ [1, 2, 3] }}
+ {{ {'foo': 'bar'} }}
+
+* Use lower cased and underscored variable names:
+
+ .. code-block:: jinja
+
+ {% set foo = 'foo' %}
+ {% set foo_bar = 'foo' %}
+
+* Indent your code inside tags (use the same indentation as the one used for
+ the target language of the rendered template):
+
+ .. code-block:: jinja
+
+ {% block foo %}
+ {% if true %}
+ true
+ {% endif %}
+ {% endblock %}
diff --git a/src/composer/vendor/twig/twig/doc/deprecated.rst b/src/composer/vendor/twig/twig/doc/deprecated.rst
new file mode 100644
index 00000000..844336b3
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/deprecated.rst
@@ -0,0 +1,160 @@
+Deprecated Features
+===================
+
+This document lists all deprecated features in Twig. Deprecated features are
+kept for backward compatibility and removed in the next major release (a
+feature that was deprecated in Twig 1.x is removed in Twig 2.0).
+
+Deprecation Notices
+-------------------
+
+As of Twig 1.21, Twig generates deprecation notices when a template uses
+deprecated features. See :ref:`deprecation-notices` for more information.
+
+Token Parsers
+-------------
+
+* As of Twig 1.x, the token parser broker sub-system is deprecated. The
+ following class and interface will be removed in 2.0:
+
+ * ``Twig_TokenParserBrokerInterface``
+ * ``Twig_TokenParserBroker``
+
+Extensions
+----------
+
+* As of Twig 1.x, the ability to remove an extension is deprecated and the
+ ``Twig_Environment::removeExtension()`` method will be removed in 2.0.
+
+* As of Twig 1.23, the ``Twig_ExtensionInterface::initRuntime()`` method is
+ deprecated. You have two options to avoid the deprecation notice: if you
+ implement this method to store the environment for your custom filters,
+ functions, or tests, use the ``needs_environment`` option instead; if you
+ have more complex needs, explicitly implement
+ ``Twig_Extension_InitRuntimeInterface`` (not recommended).
+
+* As of Twig 1.23, the ``Twig_ExtensionInterface::getGlobals()`` method is
+ deprecated. Implement ``Twig_Extension_GlobalsInterface`` to avoid
+ deprecation notices.
+
+PEAR
+----
+
+PEAR support has been discontinued in Twig 1.15.1, and no PEAR packages are
+provided anymore. Use Composer instead.
+
+Filters
+-------
+
+* As of Twig 1.x, use ``Twig_SimpleFilter`` to add a filter. The following
+ classes and interfaces will be removed in 2.0:
+
+ * ``Twig_FilterInterface``
+ * ``Twig_FilterCallableInterface``
+ * ``Twig_Filter``
+ * ``Twig_Filter_Function``
+ * ``Twig_Filter_Method``
+ * ``Twig_Filter_Node``
+
+* As of Twig 2.x, the ``Twig_SimpleFilter`` class is deprecated and will be
+ removed in Twig 3.x (use ``Twig_Filter`` instead). In Twig 2.x,
+ ``Twig_SimpleFilter`` is just an alias for ``Twig_Filter``.
+
+Functions
+---------
+
+* As of Twig 1.x, use ``Twig_SimpleFunction`` to add a function. The following
+ classes and interfaces will be removed in 2.0:
+
+ * ``Twig_FunctionInterface``
+ * ``Twig_FunctionCallableInterface``
+ * ``Twig_Function``
+ * ``Twig_Function_Function``
+ * ``Twig_Function_Method``
+ * ``Twig_Function_Node``
+
+* As of Twig 2.x, the ``Twig_SimpleFunction`` class is deprecated and will be
+ removed in Twig 3.x (use ``Twig_Function`` instead). In Twig 2.x,
+ ``Twig_SimpleFunction`` is just an alias for ``Twig_Function``.
+
+Tests
+-----
+
+* As of Twig 1.x, use ``Twig_SimpleTest`` to add a test. The following classes
+ and interfaces will be removed in 2.0:
+
+ * ``Twig_TestInterface``
+ * ``Twig_TestCallableInterface``
+ * ``Twig_Test``
+ * ``Twig_Test_Function``
+ * ``Twig_Test_Method``
+ * ``Twig_Test_Node``
+
+* As of Twig 2.x, the ``Twig_SimpleTest`` class is deprecated and will be
+ removed in Twig 3.x (use ``Twig_Test`` instead). In Twig 2.x,
+ ``Twig_SimpleTest`` is just an alias for ``Twig_Test``.
+
+* The ``sameas`` and ``divisibleby`` tests are deprecated in favor of ``same
+ as`` and ``divisible by`` respectively.
+
+Tags
+----
+
+* As of Twig 1.x, the ``raw`` tag is deprecated. You should use ``verbatim``
+ instead.
+
+Nodes
+-----
+
+* As of Twig 1.x, ``Node::toXml()`` is deprecated and will be removed in Twig
+ 2.0.
+
+Interfaces
+----------
+
+* As of Twig 2.x, the following interfaces are deprecated and empty (they will
+ be removed in Twig 3.0):
+
+* ``Twig_CompilerInterface`` (use ``Twig_Compiler`` instead)
+* ``Twig_LexerInterface`` (use ``Twig_Lexer`` instead)
+* ``Twig_NodeInterface`` (use ``Twig_Node`` instead)
+* ``Twig_ParserInterface`` (use ``Twig_Parser`` instead)
+* ``Twig_ExistsLoaderInterface`` (merged with ``Twig_LoaderInterface``)
+* ``Twig_TemplateInterface`` (use ``Twig_Template`` instead, and use
+ those constants Twig_Template::ANY_CALL, Twig_Template::ARRAY_CALL,
+ Twig_Template::METHOD_CALL)
+
+Loaders
+-------
+
+* As of Twig 1.x, ``Twig_Loader_String`` is deprecated and will be removed in
+ 2.0. You can render a string via ``Twig_Environment::createTemplate()``.
+
+Node Visitors
+-------------
+
+* Because of the removal of ``Twig_NodeInterface`` in 2.0, you need to extend
+ ``Twig_BaseNodeVisitor`` instead of implementing ``Twig_NodeVisitorInterface``
+ directly to make your node visitors compatible with both Twig 1.x and 2.x.
+
+Globals
+-------
+
+* As of Twig 2.x, the ability to register a global variable after the runtime
+ or the extensions have been initialized is not possible anymore (but
+ changing the value of an already registered global is possible).
+
+* As of Twig 1.x, the ``_self`` global variable is deprecated except for usage
+ in the ``from`` and the ``import`` tags. In Twig 2.0, ``_self`` is not
+ exposed anymore but still usable in the ``from`` and the ``import`` tags.
+
+Miscellaneous
+-------------
+
+* As of Twig 1.x, ``Twig_Environment::clearTemplateCache()``, ``Twig_Environment::writeCacheFile()``,
+ ``Twig_Environment::clearCacheFiles()``, ``Twig_Environment::getCacheFilename()``, and
+ ``Twig_Environment::getTemplateClassPrefix()`` are deprecated and will be removed in 2.0.
+
+* As of Twig 1.x, ``Twig_Template::getEnvironment()`` and
+ ``Twig_TemplateInterface::getEnvironment()`` are deprecated and will be
+ removed in 2.0.
diff --git a/src/composer/vendor/twig/twig/doc/filters/abs.rst b/src/composer/vendor/twig/twig/doc/filters/abs.rst
new file mode 100644
index 00000000..22fa59d0
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/abs.rst
@@ -0,0 +1,18 @@
+``abs``
+=======
+
+The ``abs`` filter returns the absolute value.
+
+.. code-block:: jinja
+
+ {# number = -5 #}
+
+ {{ number|abs }}
+
+ {# outputs 5 #}
+
+.. note::
+
+ Internally, Twig uses the PHP `abs`_ function.
+
+.. _`abs`: http://php.net/abs
diff --git a/src/composer/vendor/twig/twig/doc/filters/batch.rst b/src/composer/vendor/twig/twig/doc/filters/batch.rst
new file mode 100644
index 00000000..f8b6fa9d
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/batch.rst
@@ -0,0 +1,51 @@
+``batch``
+=========
+
+.. versionadded:: 1.12.3
+ The ``batch`` filter was added in Twig 1.12.3.
+
+The ``batch`` filter "batches" items by returning a list of lists with the
+given number of items. A second parameter can be provided and used to fill in
+missing items:
+
+.. code-block:: jinja
+
+ {% set items = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] %}
+
+
+ {% for row in items|batch(3, 'No item') %}
+
+ {% for column in row %}
+
{{ column }}
+ {% endfor %}
+
+ {% endfor %}
+
+
+The above example will be rendered as:
+
+.. code-block:: jinja
+
+
+
+
a
+
b
+
c
+
+
+
d
+
e
+
f
+
+
+
g
+
No item
+
No item
+
+
+
+Arguments
+---------
+
+* ``size``: The size of the batch; fractional numbers will be rounded up
+* ``fill``: Used to fill in missing items
diff --git a/src/composer/vendor/twig/twig/doc/filters/capitalize.rst b/src/composer/vendor/twig/twig/doc/filters/capitalize.rst
new file mode 100644
index 00000000..10546a1f
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/capitalize.rst
@@ -0,0 +1,11 @@
+``capitalize``
+==============
+
+The ``capitalize`` filter capitalizes a value. The first character will be
+uppercase, all others lowercase:
+
+.. code-block:: jinja
+
+ {{ 'my first car'|capitalize }}
+
+ {# outputs 'My first car' #}
diff --git a/src/composer/vendor/twig/twig/doc/filters/convert_encoding.rst b/src/composer/vendor/twig/twig/doc/filters/convert_encoding.rst
new file mode 100644
index 00000000..f4ebe580
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/convert_encoding.rst
@@ -0,0 +1,28 @@
+``convert_encoding``
+====================
+
+.. versionadded:: 1.4
+ The ``convert_encoding`` filter was added in Twig 1.4.
+
+The ``convert_encoding`` filter converts a string from one encoding to
+another. The first argument is the expected output charset and the second one
+is the input charset:
+
+.. code-block:: jinja
+
+ {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}
+
+.. note::
+
+ This filter relies on the `iconv`_ or `mbstring`_ extension, so one of
+ them must be installed. In case both are installed, `mbstring`_ is used by
+ default (Twig before 1.8.1 uses `iconv`_ by default).
+
+Arguments
+---------
+
+* ``to``: The output charset
+* ``from``: The input charset
+
+.. _`iconv`: http://php.net/iconv
+.. _`mbstring`: http://php.net/mbstring
diff --git a/src/composer/vendor/twig/twig/doc/filters/date.rst b/src/composer/vendor/twig/twig/doc/filters/date.rst
new file mode 100644
index 00000000..c86d42ba
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/date.rst
@@ -0,0 +1,94 @@
+``date``
+========
+
+.. versionadded:: 1.1
+ The timezone support has been added in Twig 1.1.
+
+.. versionadded:: 1.5
+ The default date format support has been added in Twig 1.5.
+
+.. versionadded:: 1.6.1
+ The default timezone support has been added in Twig 1.6.1.
+
+.. versionadded:: 1.11.0
+ The introduction of the false value for the timezone was introduced in Twig 1.11.0
+
+The ``date`` filter formats a date to a given format:
+
+.. code-block:: jinja
+
+ {{ post.published_at|date("m/d/Y") }}
+
+The format specifier is the same as supported by `date`_,
+except when the filtered data is of type `DateInterval`_, when the format must conform to
+`DateInterval::format`_ instead.
+
+The ``date`` filter accepts strings (it must be in a format supported by the
+`strtotime`_ function), `DateTime`_ instances, or `DateInterval`_ instances. For
+instance, to display the current date, filter the word "now":
+
+.. code-block:: jinja
+
+ {{ "now"|date("m/d/Y") }}
+
+To escape words and characters in the date format use ``\\`` in front of each
+character:
+
+.. code-block:: jinja
+
+ {{ post.published_at|date("F jS \\a\\t g:ia") }}
+
+If the value passed to the ``date`` filter is ``null``, it will return the
+current date by default. If an empty string is desired instead of the current
+date, use a ternary operator:
+
+.. code-block:: jinja
+
+ {{ post.published_at is empty ? "" : post.published_at|date("m/d/Y") }}
+
+If no format is provided, Twig will use the default one: ``F j, Y H:i``. This
+default can be easily changed by calling the ``setDateFormat()`` method on the
+``core`` extension instance. The first argument is the default format for
+dates and the second one is the default format for date intervals:
+
+.. code-block:: php
+
+ $twig = new Twig_Environment($loader);
+ $twig->getExtension('core')->setDateFormat('d/m/Y', '%d days');
+
+Timezone
+--------
+
+By default, the date is displayed by applying the default timezone (the one
+specified in php.ini or declared in Twig -- see below), but you can override
+it by explicitly specifying a timezone:
+
+.. code-block:: jinja
+
+ {{ post.published_at|date("m/d/Y", "Europe/Paris") }}
+
+If the date is already a DateTime object, and if you want to keep its current
+timezone, pass ``false`` as the timezone value:
+
+.. code-block:: jinja
+
+ {{ post.published_at|date("m/d/Y", false) }}
+
+The default timezone can also be set globally by calling ``setTimezone()``:
+
+.. code-block:: php
+
+ $twig = new Twig_Environment($loader);
+ $twig->getExtension('core')->setTimezone('Europe/Paris');
+
+Arguments
+---------
+
+* ``format``: The date format
+* ``timezone``: The date timezone
+
+.. _`strtotime`: http://www.php.net/strtotime
+.. _`DateTime`: http://www.php.net/DateTime
+.. _`DateInterval`: http://www.php.net/DateInterval
+.. _`date`: http://www.php.net/date
+.. _`DateInterval::format`: http://www.php.net/DateInterval.format
diff --git a/src/composer/vendor/twig/twig/doc/filters/date_modify.rst b/src/composer/vendor/twig/twig/doc/filters/date_modify.rst
new file mode 100644
index 00000000..add40b56
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/date_modify.rst
@@ -0,0 +1,23 @@
+``date_modify``
+===============
+
+.. versionadded:: 1.9.0
+ The date_modify filter has been added in Twig 1.9.0.
+
+The ``date_modify`` filter modifies a date with a given modifier string:
+
+.. code-block:: jinja
+
+ {{ post.published_at|date_modify("+1 day")|date("m/d/Y") }}
+
+The ``date_modify`` filter accepts strings (it must be in a format supported
+by the `strtotime`_ function) or `DateTime`_ instances. You can easily combine
+it with the :doc:`date` filter for formatting.
+
+Arguments
+---------
+
+* ``modifier``: The modifier
+
+.. _`strtotime`: http://www.php.net/strtotime
+.. _`DateTime`: http://www.php.net/DateTime
diff --git a/src/composer/vendor/twig/twig/doc/filters/default.rst b/src/composer/vendor/twig/twig/doc/filters/default.rst
new file mode 100644
index 00000000..641ac6e7
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/default.rst
@@ -0,0 +1,33 @@
+``default``
+===========
+
+The ``default`` filter returns the passed default value if the value is
+undefined or empty, otherwise the value of the variable:
+
+.. code-block:: jinja
+
+ {{ var|default('var is not defined') }}
+
+ {{ var.foo|default('foo item on var is not defined') }}
+
+ {{ var['foo']|default('foo item on var is not defined') }}
+
+ {{ ''|default('passed var is empty') }}
+
+When using the ``default`` filter on an expression that uses variables in some
+method calls, be sure to use the ``default`` filter whenever a variable can be
+undefined:
+
+.. code-block:: jinja
+
+ {{ var.method(foo|default('foo'))|default('foo') }}
+
+.. note::
+
+ Read the documentation for the :doc:`defined<../tests/defined>` and
+ :doc:`empty<../tests/empty>` tests to learn more about their semantics.
+
+Arguments
+---------
+
+* ``default``: The default value
diff --git a/src/composer/vendor/twig/twig/doc/filters/escape.rst b/src/composer/vendor/twig/twig/doc/filters/escape.rst
new file mode 100644
index 00000000..fc9771ac
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/escape.rst
@@ -0,0 +1,116 @@
+``escape``
+==========
+
+.. versionadded:: 1.9.0
+ The ``css``, ``url``, and ``html_attr`` strategies were added in Twig
+ 1.9.0.
+
+.. versionadded:: 1.14.0
+ The ability to define custom escapers was added in Twig 1.14.0.
+
+The ``escape`` filter escapes a string for safe insertion into the final
+output. It supports different escaping strategies depending on the template
+context.
+
+By default, it uses the HTML escaping strategy:
+
+.. code-block:: jinja
+
+ {{ user.username|escape }}
+
+For convenience, the ``e`` filter is defined as an alias:
+
+.. code-block:: jinja
+
+ {{ user.username|e }}
+
+The ``escape`` filter can also be used in other contexts than HTML thanks to
+an optional argument which defines the escaping strategy to use:
+
+.. code-block:: jinja
+
+ {{ user.username|e }}
+ {# is equivalent to #}
+ {{ user.username|e('html') }}
+
+And here is how to escape variables included in JavaScript code:
+
+.. code-block:: jinja
+
+ {{ user.username|escape('js') }}
+ {{ user.username|e('js') }}
+
+The ``escape`` filter supports the following escaping strategies:
+
+* ``html``: escapes a string for the **HTML body** context.
+
+* ``js``: escapes a string for the **JavaScript context**.
+
+* ``css``: escapes a string for the **CSS context**. CSS escaping can be
+ applied to any string being inserted into CSS and escapes everything except
+ alphanumerics.
+
+* ``url``: escapes a string for the **URI or parameter contexts**. This should
+ not be used to escape an entire URI; only a subcomponent being inserted.
+
+* ``html_attr``: escapes a string for the **HTML attribute** context.
+
+.. note::
+
+ Internally, ``escape`` uses the PHP native `htmlspecialchars`_ function
+ for the HTML escaping strategy.
+
+.. caution::
+
+ When using automatic escaping, Twig tries to not double-escape a variable
+ when the automatic escaping strategy is the same as the one applied by the
+ escape filter; but that does not work when using a variable as the
+ escaping strategy:
+
+ .. code-block:: jinja
+
+ {% set strategy = 'html' %}
+
+ {% autoescape 'html' %}
+ {{ var|escape('html') }} {# won't be double-escaped #}
+ {{ var|escape(strategy) }} {# will be double-escaped #}
+ {% endautoescape %}
+
+ When using a variable as the escaping strategy, you should disable
+ automatic escaping:
+
+ .. code-block:: jinja
+
+ {% set strategy = 'html' %}
+
+ {% autoescape 'html' %}
+ {{ var|escape(strategy)|raw }} {# won't be double-escaped #}
+ {% endautoescape %}
+
+Custom Escapers
+---------------
+
+You can define custom escapers by calling the ``setEscaper()`` method on the
+``core`` extension instance. The first argument is the escaper name (to be
+used in the ``escape`` call) and the second one must be a valid PHP callable:
+
+.. code-block:: php
+
+ $twig = new Twig_Environment($loader);
+ $twig->getExtension('core')->setEscaper('csv', 'csv_escaper'));
+
+When called by Twig, the callable receives the Twig environment instance, the
+string to escape, and the charset.
+
+.. note::
+
+ Built-in escapers cannot be overridden mainly they should be considered as
+ the final implementation and also for better performance.
+
+Arguments
+---------
+
+* ``strategy``: The escaping strategy
+* ``charset``: The string charset
+
+.. _`htmlspecialchars`: http://php.net/htmlspecialchars
diff --git a/src/composer/vendor/twig/twig/doc/filters/first.rst b/src/composer/vendor/twig/twig/doc/filters/first.rst
new file mode 100644
index 00000000..674c1f9e
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/first.rst
@@ -0,0 +1,25 @@
+``first``
+=========
+
+.. versionadded:: 1.12.2
+ The ``first`` filter was added in Twig 1.12.2.
+
+The ``first`` filter returns the first "element" of a sequence, a mapping, or
+a string:
+
+.. code-block:: jinja
+
+ {{ [1, 2, 3, 4]|first }}
+ {# outputs 1 #}
+
+ {{ { a: 1, b: 2, c: 3, d: 4 }|first }}
+ {# outputs 1 #}
+
+ {{ '1234'|first }}
+ {# outputs 1 #}
+
+.. note::
+
+ It also works with objects implementing the `Traversable`_ interface.
+
+.. _`Traversable`: http://php.net/manual/en/class.traversable.php
diff --git a/src/composer/vendor/twig/twig/doc/filters/format.rst b/src/composer/vendor/twig/twig/doc/filters/format.rst
new file mode 100644
index 00000000..f8effd9a
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/format.rst
@@ -0,0 +1,16 @@
+``format``
+==========
+
+The ``format`` filter formats a given string by replacing the placeholders
+(placeholders follows the `sprintf`_ notation):
+
+.. code-block:: jinja
+
+ {{ "I like %s and %s."|format(foo, "bar") }}
+
+ {# outputs I like foo and bar
+ if the foo parameter equals to the foo string. #}
+
+.. _`sprintf`: http://www.php.net/sprintf
+
+.. seealso:: :doc:`replace`
diff --git a/src/composer/vendor/twig/twig/doc/filters/index.rst b/src/composer/vendor/twig/twig/doc/filters/index.rst
new file mode 100644
index 00000000..8daa9611
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/index.rst
@@ -0,0 +1,37 @@
+Filters
+=======
+
+.. toctree::
+ :maxdepth: 1
+
+ abs
+ batch
+ capitalize
+ convert_encoding
+ date
+ date_modify
+ default
+ escape
+ first
+ format
+ join
+ json_encode
+ keys
+ last
+ length
+ lower
+ merge
+ nl2br
+ number_format
+ raw
+ replace
+ reverse
+ round
+ slice
+ sort
+ split
+ striptags
+ title
+ trim
+ upper
+ url_encode
diff --git a/src/composer/vendor/twig/twig/doc/filters/join.rst b/src/composer/vendor/twig/twig/doc/filters/join.rst
new file mode 100644
index 00000000..2fab9452
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/join.rst
@@ -0,0 +1,23 @@
+``join``
+========
+
+The ``join`` filter returns a string which is the concatenation of the items
+of a sequence:
+
+.. code-block:: jinja
+
+ {{ [1, 2, 3]|join }}
+ {# returns 123 #}
+
+The separator between elements is an empty string per default, but you can
+define it with the optional first parameter:
+
+.. code-block:: jinja
+
+ {{ [1, 2, 3]|join('|') }}
+ {# outputs 1|2|3 #}
+
+Arguments
+---------
+
+* ``glue``: The separator
diff --git a/src/composer/vendor/twig/twig/doc/filters/json_encode.rst b/src/composer/vendor/twig/twig/doc/filters/json_encode.rst
new file mode 100644
index 00000000..a39bb476
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/json_encode.rst
@@ -0,0 +1,21 @@
+``json_encode``
+===============
+
+The ``json_encode`` filter returns the JSON representation of a value:
+
+.. code-block:: jinja
+
+ {{ data|json_encode() }}
+
+.. note::
+
+ Internally, Twig uses the PHP `json_encode`_ function.
+
+Arguments
+---------
+
+* ``options``: A bitmask of `json_encode options`_ (``{{
+ data|json_encode(constant('JSON_PRETTY_PRINT')) }}``)
+
+.. _`json_encode`: http://php.net/json_encode
+.. _`json_encode options`: http://www.php.net/manual/en/json.constants.php
diff --git a/src/composer/vendor/twig/twig/doc/filters/keys.rst b/src/composer/vendor/twig/twig/doc/filters/keys.rst
new file mode 100644
index 00000000..e4f090c6
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/keys.rst
@@ -0,0 +1,11 @@
+``keys``
+========
+
+The ``keys`` filter returns the keys of an array. It is useful when you want to
+iterate over the keys of an array:
+
+.. code-block:: jinja
+
+ {% for key in array|keys %}
+ ...
+ {% endfor %}
diff --git a/src/composer/vendor/twig/twig/doc/filters/last.rst b/src/composer/vendor/twig/twig/doc/filters/last.rst
new file mode 100644
index 00000000..345b6573
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/last.rst
@@ -0,0 +1,25 @@
+``last``
+========
+
+.. versionadded:: 1.12.2
+ The ``last`` filter was added in Twig 1.12.2.
+
+The ``last`` filter returns the last "element" of a sequence, a mapping, or
+a string:
+
+.. code-block:: jinja
+
+ {{ [1, 2, 3, 4]|last }}
+ {# outputs 4 #}
+
+ {{ { a: 1, b: 2, c: 3, d: 4 }|last }}
+ {# outputs 4 #}
+
+ {{ '1234'|last }}
+ {# outputs 4 #}
+
+.. note::
+
+ It also works with objects implementing the `Traversable`_ interface.
+
+.. _`Traversable`: http://php.net/manual/en/class.traversable.php
diff --git a/src/composer/vendor/twig/twig/doc/filters/length.rst b/src/composer/vendor/twig/twig/doc/filters/length.rst
new file mode 100644
index 00000000..1f783b3d
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/length.rst
@@ -0,0 +1,11 @@
+``length``
+==========
+
+The ``length`` filter returns the number of items of a sequence or mapping, or
+the length of a string:
+
+.. code-block:: jinja
+
+ {% if users|length > 10 %}
+ ...
+ {% endif %}
diff --git a/src/composer/vendor/twig/twig/doc/filters/lower.rst b/src/composer/vendor/twig/twig/doc/filters/lower.rst
new file mode 100644
index 00000000..ef9faa90
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/lower.rst
@@ -0,0 +1,10 @@
+``lower``
+=========
+
+The ``lower`` filter converts a value to lowercase:
+
+.. code-block:: jinja
+
+ {{ 'WELCOME'|lower }}
+
+ {# outputs 'welcome' #}
diff --git a/src/composer/vendor/twig/twig/doc/filters/merge.rst b/src/composer/vendor/twig/twig/doc/filters/merge.rst
new file mode 100644
index 00000000..88780dd6
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/merge.rst
@@ -0,0 +1,48 @@
+``merge``
+=========
+
+The ``merge`` filter merges an array with another array:
+
+.. code-block:: jinja
+
+ {% set values = [1, 2] %}
+
+ {% set values = values|merge(['apple', 'orange']) %}
+
+ {# values now contains [1, 2, 'apple', 'orange'] #}
+
+New values are added at the end of the existing ones.
+
+The ``merge`` filter also works on hashes:
+
+.. code-block:: jinja
+
+ {% set items = { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'unknown' } %}
+
+ {% set items = items|merge({ 'peugeot': 'car', 'renault': 'car' }) %}
+
+ {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car', 'renault': 'car' } #}
+
+For hashes, the merging process occurs on the keys: if the key does not
+already exist, it is added but if the key already exists, its value is
+overridden.
+
+.. tip::
+
+ If you want to ensure that some values are defined in an array (by given
+ default values), reverse the two elements in the call:
+
+ .. code-block:: jinja
+
+ {% set items = { 'apple': 'fruit', 'orange': 'fruit' } %}
+
+ {% set items = { 'apple': 'unknown' }|merge(items) %}
+
+ {# items now contains { 'apple': 'fruit', 'orange': 'fruit' } #}
+
+.. note::
+
+ Internally, Twig uses the PHP `array_merge`_ function. It supports
+ Traversable objects by transforming those to arrays.
+
+.. _`array_merge`: http://php.net/array_merge
diff --git a/src/composer/vendor/twig/twig/doc/filters/nl2br.rst b/src/composer/vendor/twig/twig/doc/filters/nl2br.rst
new file mode 100644
index 00000000..5c923e14
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/nl2br.rst
@@ -0,0 +1,22 @@
+``nl2br``
+=========
+
+.. versionadded:: 1.5
+ The ``nl2br`` filter was added in Twig 1.5.
+
+The ``nl2br`` filter inserts HTML line breaks before all newlines in a string:
+
+.. code-block:: jinja
+
+ {{ "I like Twig.\nYou will like it too."|nl2br }}
+ {# outputs
+
+ I like Twig.
+ You will like it too.
+
+ #}
+
+.. note::
+
+ The ``nl2br`` filter pre-escapes the input before applying the
+ transformation.
diff --git a/src/composer/vendor/twig/twig/doc/filters/number_format.rst b/src/composer/vendor/twig/twig/doc/filters/number_format.rst
new file mode 100644
index 00000000..3114e845
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/number_format.rst
@@ -0,0 +1,45 @@
+``number_format``
+=================
+
+.. versionadded:: 1.5
+ The ``number_format`` filter was added in Twig 1.5
+
+The ``number_format`` filter formats numbers. It is a wrapper around PHP's
+`number_format`_ function:
+
+.. code-block:: jinja
+
+ {{ 200.35|number_format }}
+
+You can control the number of decimal places, decimal point, and thousands
+separator using the additional arguments:
+
+.. code-block:: jinja
+
+ {{ 9800.333|number_format(2, '.', ',') }}
+
+If no formatting options are provided then Twig will use the default formatting
+options of:
+
+* 0 decimal places.
+* ``.`` as the decimal point.
+* ``,`` as the thousands separator.
+
+These defaults can be easily changed through the core extension:
+
+.. code-block:: php
+
+ $twig = new Twig_Environment($loader);
+ $twig->getExtension('core')->setNumberFormat(3, '.', ',');
+
+The defaults set for ``number_format`` can be over-ridden upon each call using the
+additional parameters.
+
+Arguments
+---------
+
+* ``decimal``: The number of decimal points to display
+* ``decimal_point``: The character(s) to use for the decimal point
+* ``thousand_sep``: The character(s) to use for the thousands separator
+
+.. _`number_format`: http://php.net/number_format
diff --git a/src/composer/vendor/twig/twig/doc/filters/raw.rst b/src/composer/vendor/twig/twig/doc/filters/raw.rst
new file mode 100644
index 00000000..e5e5b12e
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/raw.rst
@@ -0,0 +1,36 @@
+``raw``
+=======
+
+The ``raw`` filter marks the value as being "safe", which means that in an
+environment with automatic escaping enabled this variable will not be escaped
+if ``raw`` is the last filter applied to it:
+
+.. code-block:: jinja
+
+ {% autoescape %}
+ {{ var|raw }} {# var won't be escaped #}
+ {% endautoescape %}
+
+.. note::
+
+ Be careful when using the ``raw`` filter inside expressions:
+
+ .. code-block:: jinja
+
+ {% autoescape %}
+ {% set hello = 'Hello' %}
+ {% set hola = 'Hola' %}
+
+ {{ false ? 'Hola' : hello|raw }}
+ does not render the same as
+ {{ false ? hola : hello|raw }}
+ but renders the same as
+ {{ (false ? hola : hello)|raw }}
+ {% endautoescape %}
+
+ The first ternary statement is not escaped: ``hello`` is marked as being
+ safe and Twig does not escape static values (see
+ :doc:`escape<../tags/autoescape>`). In the second ternary statement, even
+ if ``hello`` is marked as safe, ``hola`` remains unsafe and so is the whole
+ expression. The third ternary statement is marked as safe and the result is
+ not escaped.
diff --git a/src/composer/vendor/twig/twig/doc/filters/replace.rst b/src/composer/vendor/twig/twig/doc/filters/replace.rst
new file mode 100644
index 00000000..1227957b
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/replace.rst
@@ -0,0 +1,19 @@
+``replace``
+===========
+
+The ``replace`` filter formats a given string by replacing the placeholders
+(placeholders are free-form):
+
+.. code-block:: jinja
+
+ {{ "I like %this% and %that%."|replace({'%this%': foo, '%that%': "bar"}) }}
+
+ {# outputs I like foo and bar
+ if the foo parameter equals to the foo string. #}
+
+Arguments
+---------
+
+* ``replace_pairs``: The placeholder values
+
+.. seealso:: :doc:`format`
diff --git a/src/composer/vendor/twig/twig/doc/filters/reverse.rst b/src/composer/vendor/twig/twig/doc/filters/reverse.rst
new file mode 100644
index 00000000..76fd2c1a
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/reverse.rst
@@ -0,0 +1,47 @@
+``reverse``
+===========
+
+.. versionadded:: 1.6
+ Support for strings has been added in Twig 1.6.
+
+The ``reverse`` filter reverses a sequence, a mapping, or a string:
+
+.. code-block:: jinja
+
+ {% for user in users|reverse %}
+ ...
+ {% endfor %}
+
+ {{ '1234'|reverse }}
+
+ {# outputs 4321 #}
+
+.. tip::
+
+ For sequences and mappings, numeric keys are not preserved. To reverse
+ them as well, pass ``true`` as an argument to the ``reverse`` filter:
+
+ .. code-block:: jinja
+
+ {% for key, value in {1: "a", 2: "b", 3: "c"}|reverse %}
+ {{ key }}: {{ value }}
+ {%- endfor %}
+
+ {# output: 0: c 1: b 2: a #}
+
+ {% for key, value in {1: "a", 2: "b", 3: "c"}|reverse(true) %}
+ {{ key }}: {{ value }}
+ {%- endfor %}
+
+ {# output: 3: c 2: b 1: a #}
+
+.. note::
+
+ It also works with objects implementing the `Traversable`_ interface.
+
+Arguments
+---------
+
+* ``preserve_keys``: Preserve keys when reversing a mapping or a sequence.
+
+.. _`Traversable`: http://php.net/Traversable
diff --git a/src/composer/vendor/twig/twig/doc/filters/round.rst b/src/composer/vendor/twig/twig/doc/filters/round.rst
new file mode 100644
index 00000000..2521cf16
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/round.rst
@@ -0,0 +1,37 @@
+``round``
+=========
+
+.. versionadded:: 1.15.0
+ The ``round`` filter was added in Twig 1.15.0.
+
+The ``round`` filter rounds a number to a given precision:
+
+.. code-block:: jinja
+
+ {{ 42.55|round }}
+ {# outputs 43 #}
+
+ {{ 42.55|round(1, 'floor') }}
+ {# outputs 42.5 #}
+
+The ``round`` filter takes two optional arguments; the first one specifies the
+precision (default is ``0``) and the second the rounding method (default is
+``common``):
+
+* ``common`` rounds either up or down (rounds the value up to precision decimal
+ places away from zero, when it is half way there -- making 1.5 into 2 and
+ -1.5 into -2);
+
+* ``ceil`` always rounds up;
+
+* ``floor`` always rounds down.
+
+.. note::
+
+ The ``//`` operator is equivalent to ``|round(0, 'floor')``.
+
+Arguments
+---------
+
+* ``precision``: The rounding precision
+* ``method``: The rounding method
diff --git a/src/composer/vendor/twig/twig/doc/filters/slice.rst b/src/composer/vendor/twig/twig/doc/filters/slice.rst
new file mode 100644
index 00000000..70bf139e
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/slice.rst
@@ -0,0 +1,71 @@
+``slice``
+===========
+
+.. versionadded:: 1.6
+ The ``slice`` filter was added in Twig 1.6.
+
+The ``slice`` filter extracts a slice of a sequence, a mapping, or a string:
+
+.. code-block:: jinja
+
+ {% for i in [1, 2, 3, 4, 5]|slice(1, 2) %}
+ {# will iterate over 2 and 3 #}
+ {% endfor %}
+
+ {{ '12345'|slice(1, 2) }}
+
+ {# outputs 23 #}
+
+You can use any valid expression for both the start and the length:
+
+.. code-block:: jinja
+
+ {% for i in [1, 2, 3, 4, 5]|slice(start, length) %}
+ {# ... #}
+ {% endfor %}
+
+As syntactic sugar, you can also use the ``[]`` notation:
+
+.. code-block:: jinja
+
+ {% for i in [1, 2, 3, 4, 5][start:length] %}
+ {# ... #}
+ {% endfor %}
+
+ {{ '12345'[1:2] }} {# will display "23" #}
+
+ {# you can omit the first argument -- which is the same as 0 #}
+ {{ '12345'[:2] }} {# will display "12" #}
+
+ {# you can omit the last argument -- which will select everything till the end #}
+ {{ '12345'[2:] }} {# will display "345" #}
+
+The ``slice`` filter works as the `array_slice`_ PHP function for arrays and
+`mb_substr`_ for strings with a fallback to `substr`_.
+
+If the start is non-negative, the sequence will start at that start in the
+variable. If start is negative, the sequence will start that far from the end
+of the variable.
+
+If length is given and is positive, then the sequence will have up to that
+many elements in it. If the variable is shorter than the length, then only the
+available variable elements will be present. If length is given and is
+negative then the sequence will stop that many elements from the end of the
+variable. If it is omitted, then the sequence will have everything from offset
+up until the end of the variable.
+
+.. note::
+
+ It also works with objects implementing the `Traversable`_ interface.
+
+Arguments
+---------
+
+* ``start``: The start of the slice
+* ``length``: The size of the slice
+* ``preserve_keys``: Whether to preserve key or not (when the input is an array)
+
+.. _`Traversable`: http://php.net/manual/en/class.traversable.php
+.. _`array_slice`: http://php.net/array_slice
+.. _`mb_substr` : http://php.net/mb-substr
+.. _`substr`: http://php.net/substr
diff --git a/src/composer/vendor/twig/twig/doc/filters/sort.rst b/src/composer/vendor/twig/twig/doc/filters/sort.rst
new file mode 100644
index 00000000..350207f8
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/sort.rst
@@ -0,0 +1,18 @@
+``sort``
+========
+
+The ``sort`` filter sorts an array:
+
+.. code-block:: jinja
+
+ {% for user in users|sort %}
+ ...
+ {% endfor %}
+
+.. note::
+
+ Internally, Twig uses the PHP `asort`_ function to maintain index
+ association. It supports Traversable objects by transforming
+ those to arrays.
+
+.. _`asort`: http://php.net/asort
diff --git a/src/composer/vendor/twig/twig/doc/filters/split.rst b/src/composer/vendor/twig/twig/doc/filters/split.rst
new file mode 100644
index 00000000..bbc6d798
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/split.rst
@@ -0,0 +1,53 @@
+``split``
+=========
+
+.. versionadded:: 1.10.3
+ The ``split`` filter was added in Twig 1.10.3.
+
+The ``split`` filter splits a string by the given delimiter and returns a list
+of strings:
+
+.. code-block:: jinja
+
+ {% set foo = "one,two,three"|split(',') %}
+ {# foo contains ['one', 'two', 'three'] #}
+
+You can also pass a ``limit`` argument:
+
+ * If ``limit`` is positive, the returned array will contain a maximum of
+ limit elements with the last element containing the rest of string;
+
+ * If ``limit`` is negative, all components except the last -limit are
+ returned;
+
+ * If ``limit`` is zero, then this is treated as 1.
+
+.. code-block:: jinja
+
+ {% set foo = "one,two,three,four,five"|split(',', 3) %}
+ {# foo contains ['one', 'two', 'three,four,five'] #}
+
+If the ``delimiter`` is an empty string, then value will be split by equal
+chunks. Length is set by the ``limit`` argument (one character by default).
+
+.. code-block:: jinja
+
+ {% set foo = "123"|split('') %}
+ {# foo contains ['1', '2', '3'] #}
+
+ {% set bar = "aabbcc"|split('', 2) %}
+ {# bar contains ['aa', 'bb', 'cc'] #}
+
+.. note::
+
+ Internally, Twig uses the PHP `explode`_ or `str_split`_ (if delimiter is
+ empty) functions for string splitting.
+
+Arguments
+---------
+
+* ``delimiter``: The delimiter
+* ``limit``: The limit argument
+
+.. _`explode`: http://php.net/explode
+.. _`str_split`: http://php.net/str_split
diff --git a/src/composer/vendor/twig/twig/doc/filters/striptags.rst b/src/composer/vendor/twig/twig/doc/filters/striptags.rst
new file mode 100644
index 00000000..72c6f252
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/striptags.rst
@@ -0,0 +1,15 @@
+``striptags``
+=============
+
+The ``striptags`` filter strips SGML/XML tags and replace adjacent whitespace
+by one space:
+
+.. code-block:: jinja
+
+ {{ some_html|striptags }}
+
+.. note::
+
+ Internally, Twig uses the PHP `strip_tags`_ function.
+
+.. _`strip_tags`: http://php.net/strip_tags
diff --git a/src/composer/vendor/twig/twig/doc/filters/title.rst b/src/composer/vendor/twig/twig/doc/filters/title.rst
new file mode 100644
index 00000000..c5a318e8
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/title.rst
@@ -0,0 +1,11 @@
+``title``
+=========
+
+The ``title`` filter returns a titlecased version of the value. Words will
+start with uppercase letters, all remaining characters are lowercase:
+
+.. code-block:: jinja
+
+ {{ 'my first car'|title }}
+
+ {# outputs 'My First Car' #}
diff --git a/src/composer/vendor/twig/twig/doc/filters/trim.rst b/src/composer/vendor/twig/twig/doc/filters/trim.rst
new file mode 100644
index 00000000..4ddb2083
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/trim.rst
@@ -0,0 +1,29 @@
+``trim``
+========
+
+.. versionadded:: 1.6.2
+ The ``trim`` filter was added in Twig 1.6.2.
+
+The ``trim`` filter strips whitespace (or other characters) from the beginning
+and end of a string:
+
+.. code-block:: jinja
+
+ {{ ' I like Twig. '|trim }}
+
+ {# outputs 'I like Twig.' #}
+
+ {{ ' I like Twig.'|trim('.') }}
+
+ {# outputs ' I like Twig' #}
+
+.. note::
+
+ Internally, Twig uses the PHP `trim`_ function.
+
+Arguments
+---------
+
+* ``character_mask``: The characters to strip
+
+.. _`trim`: http://php.net/trim
diff --git a/src/composer/vendor/twig/twig/doc/filters/upper.rst b/src/composer/vendor/twig/twig/doc/filters/upper.rst
new file mode 100644
index 00000000..561cebe3
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/upper.rst
@@ -0,0 +1,10 @@
+``upper``
+=========
+
+The ``upper`` filter converts a value to uppercase:
+
+.. code-block:: jinja
+
+ {{ 'welcome'|upper }}
+
+ {# outputs 'WELCOME' #}
diff --git a/src/composer/vendor/twig/twig/doc/filters/url_encode.rst b/src/composer/vendor/twig/twig/doc/filters/url_encode.rst
new file mode 100644
index 00000000..5944e59c
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/filters/url_encode.rst
@@ -0,0 +1,34 @@
+``url_encode``
+==============
+
+.. versionadded:: 1.12.3
+ Support for encoding an array as query string was added in Twig 1.12.3.
+
+.. versionadded:: 1.16.0
+ The ``raw`` argument was removed in Twig 1.16.0. Twig now always encodes
+ according to RFC 3986.
+
+The ``url_encode`` filter percent encodes a given string as URL segment
+or an array as query string:
+
+.. code-block:: jinja
+
+ {{ "path-seg*ment"|url_encode }}
+ {# outputs "path-seg%2Ament" #}
+
+ {{ "string with spaces"|url_encode }}
+ {# outputs "string%20with%20spaces" #}
+
+ {{ {'param': 'value', 'foo': 'bar'}|url_encode }}
+ {# outputs "param=value&foo=bar" #}
+
+.. note::
+
+ Internally, Twig uses the PHP `urlencode`_ (or `rawurlencode`_ if you pass
+ ``true`` as the first parameter) or the `http_build_query`_ function. Note
+ that as of Twig 1.16.0, ``urlencode`` **always** uses ``rawurlencode`` (the
+ ``raw`` argument was removed.)
+
+.. _`urlencode`: http://php.net/urlencode
+.. _`rawurlencode`: http://php.net/rawurlencode
+.. _`http_build_query`: http://php.net/http_build_query
diff --git a/src/composer/vendor/twig/twig/doc/functions/attribute.rst b/src/composer/vendor/twig/twig/doc/functions/attribute.rst
new file mode 100644
index 00000000..ceba96b0
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/attribute.rst
@@ -0,0 +1,26 @@
+``attribute``
+=============
+
+.. versionadded:: 1.2
+ The ``attribute`` function was added in Twig 1.2.
+
+The ``attribute`` function can be used to access a "dynamic" attribute of a
+variable:
+
+.. code-block:: jinja
+
+ {{ attribute(object, method) }}
+ {{ attribute(object, method, arguments) }}
+ {{ attribute(array, item) }}
+
+In addition, the ``defined`` test can check for the existence of a dynamic
+attribute:
+
+.. code-block:: jinja
+
+ {{ attribute(object, method) is defined ? 'Method exists' : 'Method does not exist' }}
+
+.. note::
+
+ The resolution algorithm is the same as the one used for the ``.``
+ notation, except that the item can be any valid expression.
diff --git a/src/composer/vendor/twig/twig/doc/functions/block.rst b/src/composer/vendor/twig/twig/doc/functions/block.rst
new file mode 100644
index 00000000..fd571efb
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/block.rst
@@ -0,0 +1,15 @@
+``block``
+=========
+
+When a template uses inheritance and if you want to print a block multiple
+times, use the ``block`` function:
+
+.. code-block:: jinja
+
+ {% block title %}{% endblock %}
+
+
{{ block('title') }}
+
+ {% block body %}{% endblock %}
+
+.. seealso:: :doc:`extends<../tags/extends>`, :doc:`parent<../functions/parent>`
diff --git a/src/composer/vendor/twig/twig/doc/functions/constant.rst b/src/composer/vendor/twig/twig/doc/functions/constant.rst
new file mode 100644
index 00000000..bea0e9fc
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/constant.rst
@@ -0,0 +1,18 @@
+``constant``
+============
+
+.. versionadded: 1.12.1
+ constant now accepts object instances as the second argument.
+
+``constant`` returns the constant value for a given string:
+
+.. code-block:: jinja
+
+ {{ some_date|date(constant('DATE_W3C')) }}
+ {{ constant('Namespace\\Classname::CONSTANT_NAME') }}
+
+As of 1.12.1 you can read constants from object instances as well:
+
+.. code-block:: jinja
+
+ {{ constant('RSS', date) }}
diff --git a/src/composer/vendor/twig/twig/doc/functions/cycle.rst b/src/composer/vendor/twig/twig/doc/functions/cycle.rst
new file mode 100644
index 00000000..e3434932
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/cycle.rst
@@ -0,0 +1,28 @@
+``cycle``
+=========
+
+The ``cycle`` function cycles on an array of values:
+
+.. code-block:: jinja
+
+ {% set start_year = date() | date('Y') %}
+ {% set end_year = start_year + 5 %}
+
+ {% for year in start_year..end_year %}
+ {{ cycle(['odd', 'even'], loop.index0) }}
+ {% endfor %}
+
+The array can contain any number of values:
+
+.. code-block:: jinja
+
+ {% set fruits = ['apple', 'orange', 'citrus'] %}
+
+ {% for i in 0..10 %}
+ {{ cycle(fruits, i) }}
+ {% endfor %}
+
+Arguments
+---------
+
+* ``position``: The cycle position
diff --git a/src/composer/vendor/twig/twig/doc/functions/date.rst b/src/composer/vendor/twig/twig/doc/functions/date.rst
new file mode 100644
index 00000000..714e08c4
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/date.rst
@@ -0,0 +1,52 @@
+``date``
+========
+
+.. versionadded:: 1.6
+ The date function has been added in Twig 1.6.
+
+.. versionadded:: 1.6.1
+ The default timezone support has been added in Twig 1.6.1.
+
+Converts an argument to a date to allow date comparison:
+
+.. code-block:: jinja
+
+ {% if date(user.created_at) < date('-2days') %}
+ {# do something #}
+ {% endif %}
+
+The argument must be in one of PHP’s supported `date and time formats`_.
+
+You can pass a timezone as the second argument:
+
+.. code-block:: jinja
+
+ {% if date(user.created_at) < date('-2days', 'Europe/Paris') %}
+ {# do something #}
+ {% endif %}
+
+If no argument is passed, the function returns the current date:
+
+.. code-block:: jinja
+
+ {% if date(user.created_at) < date() %}
+ {# always! #}
+ {% endif %}
+
+.. note::
+
+ You can set the default timezone globally by calling ``setTimezone()`` on
+ the ``core`` extension instance:
+
+ .. code-block:: php
+
+ $twig = new Twig_Environment($loader);
+ $twig->getExtension('core')->setTimezone('Europe/Paris');
+
+Arguments
+---------
+
+* ``date``: The date
+* ``timezone``: The timezone
+
+.. _`date and time formats`: http://php.net/manual/en/datetime.formats.php
diff --git a/src/composer/vendor/twig/twig/doc/functions/dump.rst b/src/composer/vendor/twig/twig/doc/functions/dump.rst
new file mode 100644
index 00000000..a231f089
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/dump.rst
@@ -0,0 +1,69 @@
+``dump``
+========
+
+.. versionadded:: 1.5
+ The ``dump`` function was added in Twig 1.5.
+
+The ``dump`` function dumps information about a template variable. This is
+mostly useful to debug a template that does not behave as expected by
+introspecting its variables:
+
+.. code-block:: jinja
+
+ {{ dump(user) }}
+
+.. note::
+
+ The ``dump`` function is not available by default. You must add the
+ ``Twig_Extension_Debug`` extension explicitly when creating your Twig
+ environment::
+
+ $twig = new Twig_Environment($loader, array(
+ 'debug' => true,
+ // ...
+ ));
+ $twig->addExtension(new Twig_Extension_Debug());
+
+ Even when enabled, the ``dump`` function won't display anything if the
+ ``debug`` option on the environment is not enabled (to avoid leaking debug
+ information on a production server).
+
+In an HTML context, wrap the output with a ``pre`` tag to make it easier to
+read:
+
+.. code-block:: jinja
+
+
+ {{ dump(user) }}
+
+
+.. tip::
+
+ Using a ``pre`` tag is not needed when `XDebug`_ is enabled and
+ ``html_errors`` is ``on``; as a bonus, the output is also nicer with
+ XDebug enabled.
+
+You can debug several variables by passing them as additional arguments:
+
+.. code-block:: jinja
+
+ {{ dump(user, categories) }}
+
+If you don't pass any value, all variables from the current context are
+dumped:
+
+.. code-block:: jinja
+
+ {{ dump() }}
+
+.. note::
+
+ Internally, Twig uses the PHP `var_dump`_ function.
+
+Arguments
+---------
+
+* ``context``: The context to dump
+
+.. _`XDebug`: http://xdebug.org/docs/display
+.. _`var_dump`: http://php.net/var_dump
diff --git a/src/composer/vendor/twig/twig/doc/functions/include.rst b/src/composer/vendor/twig/twig/doc/functions/include.rst
new file mode 100644
index 00000000..33bd56d1
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/include.rst
@@ -0,0 +1,80 @@
+``include``
+===========
+
+.. versionadded:: 1.12
+ The ``include`` function was added in Twig 1.12.
+
+The ``include`` function returns the rendered content of a template:
+
+.. code-block:: jinja
+
+ {{ include('template.html') }}
+ {{ include(some_var) }}
+
+Included templates have access to the variables of the active context.
+
+If you are using the filesystem loader, the templates are looked for in the
+paths defined by it.
+
+The context is passed by default to the template but you can also pass
+additional variables:
+
+.. code-block:: jinja
+
+ {# template.html will have access to the variables from the current context and the additional ones provided #}
+ {{ include('template.html', {foo: 'bar'}) }}
+
+You can disable access to the context by setting ``with_context`` to
+``false``:
+
+.. code-block:: jinja
+
+ {# only the foo variable will be accessible #}
+ {{ include('template.html', {foo: 'bar'}, with_context = false) }}
+
+.. code-block:: jinja
+
+ {# no variables will be accessible #}
+ {{ include('template.html', with_context = false) }}
+
+And if the expression evaluates to a ``Twig_Template`` object, Twig will use it
+directly::
+
+ // {{ include(template) }}
+
+ $template = $twig->loadTemplate('some_template.twig');
+
+ $twig->loadTemplate('template.twig')->display(array('template' => $template));
+
+When you set the ``ignore_missing`` flag, Twig will return an empty string if
+the template does not exist:
+
+.. code-block:: jinja
+
+ {{ include('sidebar.html', ignore_missing = true) }}
+
+You can also provide a list of templates that are checked for existence before
+inclusion. The first template that exists will be rendered:
+
+.. code-block:: jinja
+
+ {{ include(['page_detailed.html', 'page.html']) }}
+
+If ``ignore_missing`` is set, it will fall back to rendering nothing if none
+of the templates exist, otherwise it will throw an exception.
+
+When including a template created by an end user, you should consider
+sandboxing it:
+
+.. code-block:: jinja
+
+ {{ include('page.html', sandboxed = true) }}
+
+Arguments
+---------
+
+* ``template``: The template to render
+* ``variables``: The variables to pass to the template
+* ``with_context``: Whether to pass the current context variables or not
+* ``ignore_missing``: Whether to ignore missing templates or not
+* ``sandboxed``: Whether to sandbox the template or not
diff --git a/src/composer/vendor/twig/twig/doc/functions/index.rst b/src/composer/vendor/twig/twig/doc/functions/index.rst
new file mode 100644
index 00000000..07214a76
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/index.rst
@@ -0,0 +1,20 @@
+Functions
+=========
+
+.. toctree::
+ :maxdepth: 1
+
+ attribute
+ block
+ constant
+ cycle
+ date
+ dump
+ include
+ max
+ min
+ parent
+ random
+ range
+ source
+ template_from_string
diff --git a/src/composer/vendor/twig/twig/doc/functions/max.rst b/src/composer/vendor/twig/twig/doc/functions/max.rst
new file mode 100644
index 00000000..6f3cfc53
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/max.rst
@@ -0,0 +1,20 @@
+``max``
+=======
+
+.. versionadded:: 1.15
+ The ``max`` function was added in Twig 1.15.
+
+``max`` returns the biggest value of a sequence or a set of values:
+
+.. code-block:: jinja
+
+ {{ max(1, 3, 2) }}
+ {{ max([1, 3, 2]) }}
+
+When called with a mapping, max ignores keys and only compares values:
+
+.. code-block:: jinja
+
+ {{ max({2: "e", 1: "a", 3: "b", 5: "d", 4: "c"}) }}
+ {# returns "e" #}
+
diff --git a/src/composer/vendor/twig/twig/doc/functions/min.rst b/src/composer/vendor/twig/twig/doc/functions/min.rst
new file mode 100644
index 00000000..7b6a65e1
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/min.rst
@@ -0,0 +1,20 @@
+``min``
+=======
+
+.. versionadded:: 1.15
+ The ``min`` function was added in Twig 1.15.
+
+``min`` returns the lowest value of a sequence or a set of values:
+
+.. code-block:: jinja
+
+ {{ min(1, 3, 2) }}
+ {{ min([1, 3, 2]) }}
+
+When called with a mapping, min ignores keys and only compares values:
+
+.. code-block:: jinja
+
+ {{ min({2: "e", 3: "a", 1: "b", 5: "d", 4: "c"}) }}
+ {# returns "a" #}
+
diff --git a/src/composer/vendor/twig/twig/doc/functions/parent.rst b/src/composer/vendor/twig/twig/doc/functions/parent.rst
new file mode 100644
index 00000000..f5bd2001
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/parent.rst
@@ -0,0 +1,20 @@
+``parent``
+==========
+
+When a template uses inheritance, it's possible to render the contents of the
+parent block when overriding a block by using the ``parent`` function:
+
+.. code-block:: jinja
+
+ {% extends "base.html" %}
+
+ {% block sidebar %}
+
Table Of Contents
+ ...
+ {{ parent() }}
+ {% endblock %}
+
+The ``parent()`` call will return the content of the ``sidebar`` block as
+defined in the ``base.html`` template.
+
+.. seealso:: :doc:`extends<../tags/extends>`, :doc:`block<../functions/block>`, :doc:`block<../tags/block>`
diff --git a/src/composer/vendor/twig/twig/doc/functions/random.rst b/src/composer/vendor/twig/twig/doc/functions/random.rst
new file mode 100644
index 00000000..168e74f8
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/random.rst
@@ -0,0 +1,29 @@
+``random``
+==========
+
+.. versionadded:: 1.5
+ The ``random`` function was added in Twig 1.5.
+
+.. versionadded:: 1.6
+ String and integer handling was added in Twig 1.6.
+
+The ``random`` function returns a random value depending on the supplied
+parameter type:
+
+* a random item from a sequence;
+* a random character from a string;
+* a random integer between 0 and the integer parameter (inclusive).
+
+.. code-block:: jinja
+
+ {{ random(['apple', 'orange', 'citrus']) }} {# example output: orange #}
+ {{ random('ABC') }} {# example output: C #}
+ {{ random() }} {# example output: 15386094 (works as the native PHP mt_rand function) #}
+ {{ random(5) }} {# example output: 3 #}
+
+Arguments
+---------
+
+* ``values``: The values
+
+.. _`mt_rand`: http://php.net/mt_rand
diff --git a/src/composer/vendor/twig/twig/doc/functions/range.rst b/src/composer/vendor/twig/twig/doc/functions/range.rst
new file mode 100644
index 00000000..b7cd0111
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/range.rst
@@ -0,0 +1,45 @@
+``range``
+=========
+
+Returns a list containing an arithmetic progression of integers:
+
+.. code-block:: jinja
+
+ {% for i in range(0, 3) %}
+ {{ i }},
+ {% endfor %}
+
+ {# outputs 0, 1, 2, 3, #}
+
+When step is given (as the third parameter), it specifies the increment (or
+decrement):
+
+.. code-block:: jinja
+
+ {% for i in range(0, 6, 2) %}
+ {{ i }},
+ {% endfor %}
+
+ {# outputs 0, 2, 4, 6, #}
+
+The Twig built-in ``..`` operator is just syntactic sugar for the ``range``
+function (with a step of 1):
+
+.. code-block:: jinja
+
+ {% for i in 0..3 %}
+ {{ i }},
+ {% endfor %}
+
+.. tip::
+
+ The ``range`` function works as the native PHP `range`_ function.
+
+Arguments
+---------
+
+* ``low``: The first value of the sequence.
+* ``high``: The highest possible value of the sequence.
+* ``step``: The increment between elements of the sequence.
+
+.. _`range`: http://php.net/range
diff --git a/src/composer/vendor/twig/twig/doc/functions/source.rst b/src/composer/vendor/twig/twig/doc/functions/source.rst
new file mode 100644
index 00000000..3c921b1c
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/source.rst
@@ -0,0 +1,32 @@
+``source``
+==========
+
+.. versionadded:: 1.15
+ The ``source`` function was added in Twig 1.15.
+
+.. versionadded:: 1.18.3
+ The ``ignore_missing`` flag was added in Twig 1.18.3.
+
+The ``source`` function returns the content of a template without rendering it:
+
+.. code-block:: jinja
+
+ {{ source('template.html') }}
+ {{ source(some_var) }}
+
+When you set the ``ignore_missing`` flag, Twig will return an empty string if
+the template does not exist:
+
+.. code-block:: jinja
+
+ {{ source('template.html', ignore_missing = true) }}
+
+The function uses the same template loaders as the ones used to include
+templates. So, if you are using the filesystem loader, the templates are looked
+for in the paths defined by it.
+
+Arguments
+---------
+
+* ``name``: The name of the template to read
+* ``ignore_missing``: Whether to ignore missing templates or not
diff --git a/src/composer/vendor/twig/twig/doc/functions/template_from_string.rst b/src/composer/vendor/twig/twig/doc/functions/template_from_string.rst
new file mode 100644
index 00000000..ce6a60dc
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/functions/template_from_string.rst
@@ -0,0 +1,32 @@
+``template_from_string``
+========================
+
+.. versionadded:: 1.11
+ The ``template_from_string`` function was added in Twig 1.11.
+
+The ``template_from_string`` function loads a template from a string:
+
+.. code-block:: jinja
+
+ {{ include(template_from_string("Hello {{ name }}")) }}
+ {{ include(template_from_string(page.template)) }}
+
+.. note::
+
+ The ``template_from_string`` function is not available by default. You
+ must add the ``Twig_Extension_StringLoader`` extension explicitly when
+ creating your Twig environment::
+
+ $twig = new Twig_Environment(...);
+ $twig->addExtension(new Twig_Extension_StringLoader());
+
+.. note::
+
+ Even if you will probably always use the ``template_from_string`` function
+ with the ``include`` function, you can use it with any tag or function that
+ takes a template as an argument (like the ``embed`` or ``extends`` tags).
+
+Arguments
+---------
+
+* ``template``: The template
diff --git a/src/composer/vendor/twig/twig/doc/index.rst b/src/composer/vendor/twig/twig/doc/index.rst
new file mode 100644
index 00000000..358bd738
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/index.rst
@@ -0,0 +1,19 @@
+Twig
+====
+
+.. toctree::
+ :maxdepth: 2
+
+ intro
+ installation
+ templates
+ api
+ advanced
+ internals
+ deprecated
+ recipes
+ coding_standards
+ tags/index
+ filters/index
+ functions/index
+ tests/index
diff --git a/src/composer/vendor/twig/twig/doc/installation.rst b/src/composer/vendor/twig/twig/doc/installation.rst
new file mode 100644
index 00000000..afdcf165
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/installation.rst
@@ -0,0 +1,116 @@
+Installation
+============
+
+You have multiple ways to install Twig.
+
+Installing the Twig PHP package
+-------------------------------
+
+Installing via Composer (recommended)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Install `Composer`_ and run the following command to get the latest version:
+
+.. code-block:: bash
+
+ composer require twig/twig:~1.0
+
+Installing from the tarball release
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+1. Download the most recent tarball from the `download page`_
+2. Verify the integrity of the tarball http://fabien.potencier.org/article/73/signing-project-releases
+3. Unpack the tarball
+4. Move the files somewhere in your project
+
+Installing the development version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+ git clone git://github.com/twigphp/Twig.git
+
+Installing the PEAR package
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. note::
+
+ Using PEAR for installing Twig is deprecated and Twig 1.15.1 was the last
+ version published on the PEAR channel; use Composer instead.
+
+.. code-block:: bash
+
+ pear channel-discover pear.twig-project.org
+ pear install twig/Twig
+
+Installing the C extension
+--------------------------
+
+.. versionadded:: 1.4
+ The C extension was added in Twig 1.4.
+
+.. note::
+
+ The C extension is **optional** but it brings some nice performance
+ improvements. Note that the extension is not a replacement for the PHP
+ code; it only implements a small part of the PHP code to improve the
+ performance at runtime; you must still install the regular PHP code.
+
+Twig comes with a C extension that enhances the performance of the Twig
+runtime engine; install it like any other PHP extensions:
+
+.. code-block:: bash
+
+ cd ext/twig
+ phpize
+ ./configure
+ make
+ make install
+
+.. note::
+
+ You can also install the C extension via PEAR (note that this method is
+ deprecated and newer versions of Twig are not available on the PEAR
+ channel):
+
+ .. code-block:: bash
+
+ pear channel-discover pear.twig-project.org
+ pear install twig/CTwig
+
+For Windows:
+
+1. Setup the build environment following the `PHP documentation`_
+2. Put Twig's C extension source code into ``C:\php-sdk\phpdev\vcXX\x86\php-source-directory\ext\twig``
+3. Use the ``configure --disable-all --enable-cli --enable-twig=shared`` command instead of step 14
+4. ``nmake``
+5. Copy the ``C:\php-sdk\phpdev\vcXX\x86\php-source-directory\Release_TS\php_twig.dll`` file to your PHP setup.
+
+.. tip::
+
+ For Windows ZendServer, ZTS is not enabled as mentioned in `Zend Server
+ FAQ`_.
+
+ You have to use ``configure --disable-all --disable-zts --enable-cli
+ --enable-twig=shared`` to be able to build the twig C extension for
+ ZendServer.
+
+ The built DLL will be available in
+ ``C:\\php-sdk\\phpdev\\vcXX\\x86\\php-source-directory\\Release``
+
+Finally, enable the extension in your ``php.ini`` configuration file:
+
+.. code-block:: ini
+
+ extension=twig.so #For Unix systems
+ extension=php_twig.dll #For Windows systems
+
+And from now on, Twig will automatically compile your templates to take
+advantage of the C extension. Note that this extension does not replace the
+PHP code but only provides an optimized version of the
+``Twig_Template::getAttribute()`` method.
+
+.. _`download page`: https://github.com/twigphp/Twig/tags
+.. _`Composer`: https://getcomposer.org/download/
+.. _`PHP documentation`: https://wiki.php.net/internals/windows/stepbystepbuild
+.. _`Zend Server FAQ`: http://www.zend.com/en/products/server/faq#faqD6
diff --git a/src/composer/vendor/twig/twig/doc/internals.rst b/src/composer/vendor/twig/twig/doc/internals.rst
new file mode 100644
index 00000000..ef1174dd
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/internals.rst
@@ -0,0 +1,138 @@
+Twig Internals
+==============
+
+Twig is very extensible and you can easily hack it. Keep in mind that you
+should probably try to create an extension before hacking the core, as most
+features and enhancements can be handled with extensions. This chapter is also
+useful for people who want to understand how Twig works under the hood.
+
+How does Twig work?
+-------------------
+
+The rendering of a Twig template can be summarized into four key steps:
+
+* **Load** the template: If the template is already compiled, load it and go
+ to the *evaluation* step, otherwise:
+
+ * First, the **lexer** tokenizes the template source code into small pieces
+ for easier processing;
+ * Then, the **parser** converts the token stream into a meaningful tree
+ of nodes (the Abstract Syntax Tree);
+ * Eventually, the *compiler* transforms the AST into PHP code.
+
+* **Evaluate** the template: It basically means calling the ``display()``
+ method of the compiled template and passing it the context.
+
+The Lexer
+---------
+
+The lexer tokenizes a template source code into a token stream (each token is
+an instance of ``Twig_Token``, and the stream is an instance of
+``Twig_TokenStream``). The default lexer recognizes 13 different token types:
+
+* ``Twig_Token::BLOCK_START_TYPE``, ``Twig_Token::BLOCK_END_TYPE``: Delimiters for blocks (``{% %}``)
+* ``Twig_Token::VAR_START_TYPE``, ``Twig_Token::VAR_END_TYPE``: Delimiters for variables (``{{ }}``)
+* ``Twig_Token::TEXT_TYPE``: A text outside an expression;
+* ``Twig_Token::NAME_TYPE``: A name in an expression;
+* ``Twig_Token::NUMBER_TYPE``: A number in an expression;
+* ``Twig_Token::STRING_TYPE``: A string in an expression;
+* ``Twig_Token::OPERATOR_TYPE``: An operator;
+* ``Twig_Token::PUNCTUATION_TYPE``: A punctuation sign;
+* ``Twig_Token::INTERPOLATION_START_TYPE``, ``Twig_Token::INTERPOLATION_END_TYPE`` (as of Twig 1.5): Delimiters for string interpolation;
+* ``Twig_Token::EOF_TYPE``: Ends of template.
+
+You can manually convert a source code into a token stream by calling the
+``tokenize()`` method of an environment::
+
+ $stream = $twig->tokenize($source, $identifier);
+
+As the stream has a ``__toString()`` method, you can have a textual
+representation of it by echoing the object::
+
+ echo $stream."\n";
+
+Here is the output for the ``Hello {{ name }}`` template:
+
+.. code-block:: text
+
+ TEXT_TYPE(Hello )
+ VAR_START_TYPE()
+ NAME_TYPE(name)
+ VAR_END_TYPE()
+ EOF_TYPE()
+
+.. note::
+
+ The default lexer (``Twig_Lexer``) can be changed by calling
+ the ``setLexer()`` method::
+
+ $twig->setLexer($lexer);
+
+The Parser
+----------
+
+The parser converts the token stream into an AST (Abstract Syntax Tree), or a
+node tree (an instance of ``Twig_Node_Module``). The core extension defines
+the basic nodes like: ``for``, ``if``, ... and the expression nodes.
+
+You can manually convert a token stream into a node tree by calling the
+``parse()`` method of an environment::
+
+ $nodes = $twig->parse($stream);
+
+Echoing the node object gives you a nice representation of the tree::
+
+ echo $nodes."\n";
+
+Here is the output for the ``Hello {{ name }}`` template:
+
+.. code-block:: text
+
+ Twig_Node_Module(
+ Twig_Node_Text(Hello )
+ Twig_Node_Print(
+ Twig_Node_Expression_Name(name)
+ )
+ )
+
+.. note::
+
+ The default parser (``Twig_TokenParser``) can be changed by calling the
+ ``setParser()`` method::
+
+ $twig->setParser($parser);
+
+The Compiler
+------------
+
+The last step is done by the compiler. It takes a node tree as an input and
+generates PHP code usable for runtime execution of the template.
+
+You can manually compile a node tree to PHP code with the ``compile()`` method
+of an environment::
+
+ $php = $twig->compile($nodes);
+
+The generated template for a ``Hello {{ name }}`` template reads as follows
+(the actual output can differ depending on the version of Twig you are
+using)::
+
+ /* Hello {{ name }} */
+ class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Twig_Template
+ {
+ protected function doDisplay(array $context, array $blocks = array())
+ {
+ // line 1
+ echo "Hello ";
+ echo twig_escape_filter($this->env, isset($context["name"]) ? $context["name"] : null), "html", null, true);
+ }
+
+ // some more code
+ }
+
+.. note::
+
+ The default compiler (``Twig_Compiler``) can be changed by calling the
+ ``setCompiler()`` method::
+
+ $twig->setCompiler($compiler);
diff --git a/src/composer/vendor/twig/twig/doc/intro.rst b/src/composer/vendor/twig/twig/doc/intro.rst
new file mode 100644
index 00000000..9b38c97d
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/intro.rst
@@ -0,0 +1,85 @@
+Introduction
+============
+
+This is the documentation for Twig, the flexible, fast, and secure template
+engine for PHP.
+
+If you have any exposure to other text-based template languages, such as
+Smarty, Django, or Jinja, you should feel right at home with Twig. It's both
+designer and developer friendly by sticking to PHP's principles and adding
+functionality useful for templating environments.
+
+The key-features are...
+
+* *Fast*: Twig compiles templates down to plain optimized PHP code. The
+ overhead compared to regular PHP code was reduced to the very minimum.
+
+* *Secure*: Twig has a sandbox mode to evaluate untrusted template code. This
+ allows Twig to be used as a template language for applications where users
+ may modify the template design.
+
+* *Flexible*: Twig is powered by a flexible lexer and parser. This allows the
+ developer to define its own custom tags and filters, and create its own DSL.
+
+Twig is used by many Open-Source projects like Symfony, Drupal8, eZPublish,
+phpBB, Piwik, OroCRM, and many frameworks have support for it as well like
+Slim, Yii, Laravel, Codeigniter, and Kohana, just to name a few.
+
+Prerequisites
+-------------
+
+Twig needs at least **PHP 5.2.7** to run.
+
+Installation
+------------
+
+The recommended way to install Twig is via Composer:
+
+.. code-block:: bash
+
+ composer require "twig/twig:~1.0"
+
+.. note::
+
+ To learn more about the other installation methods, read the
+ :doc:`installation` chapter; it also explains how to install
+ the Twig C extension.
+
+Basic API Usage
+---------------
+
+This section gives you a brief introduction to the PHP API for Twig.
+
+.. code-block:: php
+
+ require_once '/path/to/vendor/autoload.php';
+
+ $loader = new Twig_Loader_Array(array(
+ 'index' => 'Hello {{ name }}!',
+ ));
+ $twig = new Twig_Environment($loader);
+
+ echo $twig->render('index', array('name' => 'Fabien'));
+
+Twig uses a loader (``Twig_Loader_Array``) to locate templates, and an
+environment (``Twig_Environment``) to store the configuration.
+
+The ``render()`` method loads the template passed as a first argument and
+renders it with the variables passed as a second argument.
+
+As templates are generally stored on the filesystem, Twig also comes with a
+filesystem loader::
+
+ $loader = new Twig_Loader_Filesystem('/path/to/templates');
+ $twig = new Twig_Environment($loader, array(
+ 'cache' => '/path/to/compilation_cache',
+ ));
+
+ echo $twig->render('index.html', array('name' => 'Fabien'));
+
+.. tip::
+
+ If you are not using Composer, use the Twig built-in autoloader::
+
+ require_once '/path/to/lib/Twig/Autoloader.php';
+ Twig_Autoloader::register();
diff --git a/src/composer/vendor/twig/twig/doc/recipes.rst b/src/composer/vendor/twig/twig/doc/recipes.rst
new file mode 100644
index 00000000..6ad53276
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/recipes.rst
@@ -0,0 +1,518 @@
+Recipes
+=======
+
+.. _deprecation-notices:
+
+Displaying Deprecation Notices
+------------------------------
+
+.. versionadded:: 1.21
+ This works as of Twig 1.21.
+
+Deprecated features generate deprecation notices (via a call to the
+``trigger_error()`` PHP function). By default, they are silenced and never
+displayed nor logged.
+
+To easily remove all deprecated feature usages from your templates, write and
+run a script along the lines of the following::
+
+ require_once __DIR__.'/vendor/autoload.php';
+
+ $twig = create_your_twig_env();
+
+ $deprecations = new Twig_Util_DeprecationCollector($twig);
+
+ print_r($deprecations->collectDir(__DIR__.'/templates'));
+
+The ``collectDir()`` method compiles all templates found in a directory,
+catches deprecation notices, and return them.
+
+.. tip::
+
+ If your templates are not stored on the filesystem, use the ``collect()``
+ method instead which takes an ``Iterator``; the iterator must return
+ template names as keys and template contents as values (as done by
+ ``Twig_Util_TemplateDirIterator``).
+
+However, this code won't find all deprecations (like using deprecated some Twig
+classes). To catch all notices, register a custom error handler like the one
+below::
+
+ $deprecations = array();
+ set_error_handler(function ($type, $msg) use (&$deprecations) {
+ if (E_USER_DEPRECATED === $type) {
+ $deprecations[] = $msg;
+ }
+ });
+
+ // run your application
+
+ print_r($deprecations);
+
+Note that most deprecation notices are triggered during **compilation**, so
+they won't be generated when templates are already cached.
+
+.. tip::
+
+ If you want to manage the deprecation notices from your PHPUnit tests, have
+ a look at the `symfony/phpunit-bridge
+ `_ package, which eases the
+ process a lot.
+
+Making a Layout conditional
+---------------------------
+
+Working with Ajax means that the same content is sometimes displayed as is,
+and sometimes decorated with a layout. As Twig layout template names can be
+any valid expression, you can pass a variable that evaluates to ``true`` when
+the request is made via Ajax and choose the layout accordingly:
+
+.. code-block:: jinja
+
+ {% extends request.ajax ? "base_ajax.html" : "base.html" %}
+
+ {% block content %}
+ This is the content to be displayed.
+ {% endblock %}
+
+Making an Include dynamic
+-------------------------
+
+When including a template, its name does not need to be a string. For
+instance, the name can depend on the value of a variable:
+
+.. code-block:: jinja
+
+ {% include var ~ '_foo.html' %}
+
+If ``var`` evaluates to ``index``, the ``index_foo.html`` template will be
+rendered.
+
+As a matter of fact, the template name can be any valid expression, such as
+the following:
+
+.. code-block:: jinja
+
+ {% include var|default('index') ~ '_foo.html' %}
+
+Overriding a Template that also extends itself
+----------------------------------------------
+
+A template can be customized in two different ways:
+
+* *Inheritance*: A template *extends* a parent template and overrides some
+ blocks;
+
+* *Replacement*: If you use the filesystem loader, Twig loads the first
+ template it finds in a list of configured directories; a template found in a
+ directory *replaces* another one from a directory further in the list.
+
+But how do you combine both: *replace* a template that also extends itself
+(aka a template in a directory further in the list)?
+
+Let's say that your templates are loaded from both ``.../templates/mysite``
+and ``.../templates/default`` in this order. The ``page.twig`` template,
+stored in ``.../templates/default`` reads as follows:
+
+.. code-block:: jinja
+
+ {# page.twig #}
+ {% extends "layout.twig" %}
+
+ {% block content %}
+ {% endblock %}
+
+You can replace this template by putting a file with the same name in
+``.../templates/mysite``. And if you want to extend the original template, you
+might be tempted to write the following:
+
+.. code-block:: jinja
+
+ {# page.twig in .../templates/mysite #}
+ {% extends "page.twig" %} {# from .../templates/default #}
+
+Of course, this will not work as Twig will always load the template from
+``.../templates/mysite``.
+
+It turns out it is possible to get this to work, by adding a directory right
+at the end of your template directories, which is the parent of all of the
+other directories: ``.../templates`` in our case. This has the effect of
+making every template file within our system uniquely addressable. Most of the
+time you will use the "normal" paths, but in the special case of wanting to
+extend a template with an overriding version of itself we can reference its
+parent's full, unambiguous template path in the extends tag:
+
+.. code-block:: jinja
+
+ {# page.twig in .../templates/mysite #}
+ {% extends "default/page.twig" %} {# from .../templates #}
+
+.. note::
+
+ This recipe was inspired by the following Django wiki page:
+ http://code.djangoproject.com/wiki/ExtendingTemplates
+
+Customizing the Syntax
+----------------------
+
+Twig allows some syntax customization for the block delimiters. It's not
+recommended to use this feature as templates will be tied with your custom
+syntax. But for specific projects, it can make sense to change the defaults.
+
+To change the block delimiters, you need to create your own lexer object::
+
+ $twig = new Twig_Environment();
+
+ $lexer = new Twig_Lexer($twig, array(
+ 'tag_comment' => array('{#', '#}'),
+ 'tag_block' => array('{%', '%}'),
+ 'tag_variable' => array('{{', '}}'),
+ 'interpolation' => array('#{', '}'),
+ ));
+ $twig->setLexer($lexer);
+
+Here are some configuration example that simulates some other template engines
+syntax::
+
+ // Ruby erb syntax
+ $lexer = new Twig_Lexer($twig, array(
+ 'tag_comment' => array('<%#', '%>'),
+ 'tag_block' => array('<%', '%>'),
+ 'tag_variable' => array('<%=', '%>'),
+ ));
+
+ // SGML Comment Syntax
+ $lexer = new Twig_Lexer($twig, array(
+ 'tag_comment' => array(''),
+ 'tag_block' => array(''),
+ 'tag_variable' => array('${', '}'),
+ ));
+
+ // Smarty like
+ $lexer = new Twig_Lexer($twig, array(
+ 'tag_comment' => array('{*', '*}'),
+ 'tag_block' => array('{', '}'),
+ 'tag_variable' => array('{$', '}'),
+ ));
+
+Using dynamic Object Properties
+-------------------------------
+
+When Twig encounters a variable like ``article.title``, it tries to find a
+``title`` public property in the ``article`` object.
+
+It also works if the property does not exist but is rather defined dynamically
+thanks to the magic ``__get()`` method; you just need to also implement the
+``__isset()`` magic method like shown in the following snippet of code::
+
+ class Article
+ {
+ public function __get($name)
+ {
+ if ('title' == $name) {
+ return 'The title';
+ }
+
+ // throw some kind of error
+ }
+
+ public function __isset($name)
+ {
+ if ('title' == $name) {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+Accessing the parent Context in Nested Loops
+--------------------------------------------
+
+Sometimes, when using nested loops, you need to access the parent context. The
+parent context is always accessible via the ``loop.parent`` variable. For
+instance, if you have the following template data::
+
+ $data = array(
+ 'topics' => array(
+ 'topic1' => array('Message 1 of topic 1', 'Message 2 of topic 1'),
+ 'topic2' => array('Message 1 of topic 2', 'Message 2 of topic 2'),
+ ),
+ );
+
+And the following template to display all messages in all topics:
+
+.. code-block:: jinja
+
+ {% for topic, messages in topics %}
+ * {{ loop.index }}: {{ topic }}
+ {% for message in messages %}
+ - {{ loop.parent.loop.index }}.{{ loop.index }}: {{ message }}
+ {% endfor %}
+ {% endfor %}
+
+The output will be similar to:
+
+.. code-block:: text
+
+ * 1: topic1
+ - 1.1: The message 1 of topic 1
+ - 1.2: The message 2 of topic 1
+ * 2: topic2
+ - 2.1: The message 1 of topic 2
+ - 2.2: The message 2 of topic 2
+
+In the inner loop, the ``loop.parent`` variable is used to access the outer
+context. So, the index of the current ``topic`` defined in the outer for loop
+is accessible via the ``loop.parent.loop.index`` variable.
+
+Defining undefined Functions and Filters on the Fly
+---------------------------------------------------
+
+When a function (or a filter) is not defined, Twig defaults to throw a
+``Twig_Error_Syntax`` exception. However, it can also call a `callback`_ (any
+valid PHP callable) which should return a function (or a filter).
+
+For filters, register callbacks with ``registerUndefinedFilterCallback()``.
+For functions, use ``registerUndefinedFunctionCallback()``::
+
+ // auto-register all native PHP functions as Twig functions
+ // don't try this at home as it's not secure at all!
+ $twig->registerUndefinedFunctionCallback(function ($name) {
+ if (function_exists($name)) {
+ return new Twig_Function_Function($name);
+ }
+
+ return false;
+ });
+
+If the callable is not able to return a valid function (or filter), it must
+return ``false``.
+
+If you register more than one callback, Twig will call them in turn until one
+does not return ``false``.
+
+.. tip::
+
+ As the resolution of functions and filters is done during compilation,
+ there is no overhead when registering these callbacks.
+
+Validating the Template Syntax
+------------------------------
+
+When template code is provided by a third-party (through a web interface for
+instance), it might be interesting to validate the template syntax before
+saving it. If the template code is stored in a `$template` variable, here is
+how you can do it::
+
+ try {
+ $twig->parse($twig->tokenize($template));
+
+ // the $template is valid
+ } catch (Twig_Error_Syntax $e) {
+ // $template contains one or more syntax errors
+ }
+
+If you iterate over a set of files, you can pass the filename to the
+``tokenize()`` method to get the filename in the exception message::
+
+ foreach ($files as $file) {
+ try {
+ $twig->parse($twig->tokenize($template, $file));
+
+ // the $template is valid
+ } catch (Twig_Error_Syntax $e) {
+ // $template contains one or more syntax errors
+ }
+ }
+
+.. note::
+
+ This method won't catch any sandbox policy violations because the policy
+ is enforced during template rendering (as Twig needs the context for some
+ checks like allowed methods on objects).
+
+Refreshing modified Templates when OPcache or APC is enabled
+------------------------------------------------------------
+
+When using OPcache with ``opcache.validate_timestamps`` set to ``0`` or APC
+with ``apc.stat`` set to ``0`` and Twig cache enabled, clearing the template
+cache won't update the cache.
+
+To get around this, force Twig to invalidate the bytecode cache::
+
+ $twig = new Twig_Environment($loader, array(
+ 'cache' => new Twig_Cache_Filesystem('/some/cache/path', Twig_Cache_Filesystem::FORCE_BYTECODE_INVALIDATION),
+ // ...
+ ));
+
+.. note::
+
+ Before Twig 1.22, you should extend ``Twig_Environment`` instead::
+
+ class OpCacheAwareTwigEnvironment extends Twig_Environment
+ {
+ protected function writeCacheFile($file, $content)
+ {
+ parent::writeCacheFile($file, $content);
+
+ // Compile cached file into bytecode cache
+ if (function_exists('opcache_invalidate')) {
+ opcache_invalidate($file, true);
+ } elseif (function_exists('apc_compile_file')) {
+ apc_compile_file($file);
+ }
+ }
+ }
+
+Reusing a stateful Node Visitor
+-------------------------------
+
+When attaching a visitor to a ``Twig_Environment`` instance, Twig uses it to
+visit *all* templates it compiles. If you need to keep some state information
+around, you probably want to reset it when visiting a new template.
+
+This can be easily achieved with the following code::
+
+ protected $someTemplateState = array();
+
+ public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
+ {
+ if ($node instanceof Twig_Node_Module) {
+ // reset the state as we are entering a new template
+ $this->someTemplateState = array();
+ }
+
+ // ...
+
+ return $node;
+ }
+
+Using a Database to store Templates
+-----------------------------------
+
+If you are developing a CMS, templates are usually stored in a database. This
+recipe gives you a simple PDO template loader you can use as a starting point
+for your own.
+
+First, let's create a temporary in-memory SQLite3 database to work with::
+
+ $dbh = new PDO('sqlite::memory:');
+ $dbh->exec('CREATE TABLE templates (name STRING, source STRING, last_modified INTEGER)');
+ $base = '{% block content %}{% endblock %}';
+ $index = '
+ {% extends "base.twig" %}
+ {% block content %}Hello {{ name }}{% endblock %}
+ ';
+ $now = time();
+ $dbh->exec("INSERT INTO templates (name, source, last_modified) VALUES ('base.twig', '$base', $now)");
+ $dbh->exec("INSERT INTO templates (name, source, last_modified) VALUES ('index.twig', '$index', $now)");
+
+We have created a simple ``templates`` table that hosts two templates:
+``base.twig`` and ``index.twig``.
+
+Now, let's define a loader able to use this database::
+
+ class DatabaseTwigLoader implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
+ {
+ protected $dbh;
+
+ public function __construct(PDO $dbh)
+ {
+ $this->dbh = $dbh;
+ }
+
+ public function getSource($name)
+ {
+ if (false === $source = $this->getValue('source', $name)) {
+ throw new Twig_Error_Loader(sprintf('Template "%s" does not exist.', $name));
+ }
+
+ return $source;
+ }
+
+ // Twig_ExistsLoaderInterface as of Twig 1.11
+ public function exists($name)
+ {
+ return $name === $this->getValue('name', $name);
+ }
+
+ public function getCacheKey($name)
+ {
+ return $name;
+ }
+
+ public function isFresh($name, $time)
+ {
+ if (false === $lastModified = $this->getValue('last_modified', $name)) {
+ return false;
+ }
+
+ return $lastModified <= $time;
+ }
+
+ protected function getValue($column, $name)
+ {
+ $sth = $this->dbh->prepare('SELECT '.$column.' FROM templates WHERE name = :name');
+ $sth->execute(array(':name' => (string) $name));
+
+ return $sth->fetchColumn();
+ }
+ }
+
+Finally, here is an example on how you can use it::
+
+ $loader = new DatabaseTwigLoader($dbh);
+ $twig = new Twig_Environment($loader);
+
+ echo $twig->render('index.twig', array('name' => 'Fabien'));
+
+Using different Template Sources
+--------------------------------
+
+This recipe is the continuation of the previous one. Even if you store the
+contributed templates in a database, you might want to keep the original/base
+templates on the filesystem. When templates can be loaded from different
+sources, you need to use the ``Twig_Loader_Chain`` loader.
+
+As you can see in the previous recipe, we reference the template in the exact
+same way as we would have done it with a regular filesystem loader. This is
+the key to be able to mix and match templates coming from the database, the
+filesystem, or any other loader for that matter: the template name should be a
+logical name, and not the path from the filesystem::
+
+ $loader1 = new DatabaseTwigLoader($dbh);
+ $loader2 = new Twig_Loader_Array(array(
+ 'base.twig' => '{% block content %}{% endblock %}',
+ ));
+ $loader = new Twig_Loader_Chain(array($loader1, $loader2));
+
+ $twig = new Twig_Environment($loader);
+
+ echo $twig->render('index.twig', array('name' => 'Fabien'));
+
+Now that the ``base.twig`` templates is defined in an array loader, you can
+remove it from the database, and everything else will still work as before.
+
+Loading a Template from a String
+--------------------------------
+
+From a template, you can easily load a template stored in a string via the
+``template_from_string`` function (available as of Twig 1.11 via the
+``Twig_Extension_StringLoader`` extension)::
+
+.. code-block:: jinja
+
+ {{ include(template_from_string("Hello {{ name }}")) }}
+
+From PHP, it's also possible to load a template stored in a string via
+``Twig_Environment::createTemplate()`` (available as of Twig 1.18)::
+
+ $template = $twig->createTemplate('hello {{ name }}');
+ echo $template->render(array('name' => 'Fabien'));
+
+.. note::
+
+ Never use the ``Twig_Loader_String`` loader, which has severe limitations.
+
+.. _callback: http://www.php.net/manual/en/function.is-callable.php
diff --git a/src/composer/vendor/twig/twig/doc/tags/autoescape.rst b/src/composer/vendor/twig/twig/doc/tags/autoescape.rst
new file mode 100644
index 00000000..4208d1a3
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/tags/autoescape.rst
@@ -0,0 +1,83 @@
+``autoescape``
+==============
+
+Whether automatic escaping is enabled or not, you can mark a section of a
+template to be escaped or not by using the ``autoescape`` tag:
+
+.. code-block:: jinja
+
+ {# The following syntax works as of Twig 1.8 -- see the note below for previous versions #}
+
+ {% autoescape %}
+ Everything will be automatically escaped in this block
+ using the HTML strategy
+ {% endautoescape %}
+
+ {% autoescape 'html' %}
+ Everything will be automatically escaped in this block
+ using the HTML strategy
+ {% endautoescape %}
+
+ {% autoescape 'js' %}
+ Everything will be automatically escaped in this block
+ using the js escaping strategy
+ {% endautoescape %}
+
+ {% autoescape false %}
+ Everything will be outputted as is in this block
+ {% endautoescape %}
+
+.. note::
+
+ Before Twig 1.8, the syntax was different:
+
+ .. code-block:: jinja
+
+ {% autoescape true %}
+ Everything will be automatically escaped in this block
+ using the HTML strategy
+ {% endautoescape %}
+
+ {% autoescape false %}
+ Everything will be outputted as is in this block
+ {% endautoescape %}
+
+ {% autoescape true js %}
+ Everything will be automatically escaped in this block
+ using the js escaping strategy
+ {% endautoescape %}
+
+When automatic escaping is enabled everything is escaped by default except for
+values explicitly marked as safe. Those can be marked in the template by using
+the :doc:`raw<../filters/raw>` filter:
+
+.. code-block:: jinja
+
+ {% autoescape %}
+ {{ safe_value|raw }}
+ {% endautoescape %}
+
+Functions returning template data (like :doc:`macros` and
+:doc:`parent<../functions/parent>`) always return safe markup.
+
+.. note::
+
+ Twig is smart enough to not escape an already escaped value by the
+ :doc:`escape<../filters/escape>` filter.
+
+.. note::
+
+ Twig does not escape static expressions:
+
+ .. code-block:: jinja
+
+ {% set hello = "Hello" %}
+ {{ hello }}
+ {{ "world" }}
+
+ Will be rendered "Hello **world**".
+
+.. note::
+
+ The chapter :doc:`Twig for Developers<../api>` gives more information
+ about when and how automatic escaping is applied.
diff --git a/src/composer/vendor/twig/twig/doc/tags/block.rst b/src/composer/vendor/twig/twig/doc/tags/block.rst
new file mode 100644
index 00000000..e3804823
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/tags/block.rst
@@ -0,0 +1,11 @@
+``block``
+=========
+
+Blocks are used for inheritance and act as placeholders and replacements at
+the same time. They are documented in detail in the documentation for the
+:doc:`extends<../tags/extends>` tag.
+
+Block names should consist of alphanumeric characters, and underscores. Dashes
+are not permitted.
+
+.. seealso:: :doc:`block<../functions/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`, :doc:`extends<../tags/extends>`
diff --git a/src/composer/vendor/twig/twig/doc/tags/do.rst b/src/composer/vendor/twig/twig/doc/tags/do.rst
new file mode 100644
index 00000000..1c344e30
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/tags/do.rst
@@ -0,0 +1,12 @@
+``do``
+======
+
+.. versionadded:: 1.5
+ The ``do`` tag was added in Twig 1.5.
+
+The ``do`` tag works exactly like the regular variable expression (``{{ ...
+}}``) just that it doesn't print anything:
+
+.. code-block:: jinja
+
+ {% do 1 + 2 %}
diff --git a/src/composer/vendor/twig/twig/doc/tags/embed.rst b/src/composer/vendor/twig/twig/doc/tags/embed.rst
new file mode 100644
index 00000000..5a6a0299
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/tags/embed.rst
@@ -0,0 +1,178 @@
+``embed``
+=========
+
+.. versionadded:: 1.8
+ The ``embed`` tag was added in Twig 1.8.
+
+The ``embed`` tag combines the behaviour of :doc:`include` and
+:doc:`extends`.
+It allows you to include another template's contents, just like ``include``
+does. But it also allows you to override any block defined inside the
+included template, like when extending a template.
+
+Think of an embedded template as a "micro layout skeleton".
+
+.. code-block:: jinja
+
+ {% embed "teasers_skeleton.twig" %}
+ {# These blocks are defined in "teasers_skeleton.twig" #}
+ {# and we override them right here: #}
+ {% block left_teaser %}
+ Some content for the left teaser box
+ {% endblock %}
+ {% block right_teaser %}
+ Some content for the right teaser box
+ {% endblock %}
+ {% endembed %}
+
+The ``embed`` tag takes the idea of template inheritance to the level of
+content fragments. While template inheritance allows for "document skeletons",
+which are filled with life by child templates, the ``embed`` tag allows you to
+create "skeletons" for smaller units of content and re-use and fill them
+anywhere you like.
+
+Since the use case may not be obvious, let's look at a simplified example.
+Imagine a base template shared by multiple HTML pages, defining a single block
+named "content":
+
+.. code-block:: text
+
+ ┌─── page layout ─────────────────────┐
+ │ │
+ │ ┌── block "content" ──┐ │
+ │ │ │ │
+ │ │ │ │
+ │ │ (child template to │ │
+ │ │ put content here) │ │
+ │ │ │ │
+ │ │ │ │
+ │ └─────────────────────┘ │
+ │ │
+ └─────────────────────────────────────┘
+
+Some pages ("foo" and "bar") share the same content structure -
+two vertically stacked boxes:
+
+.. code-block:: text
+
+ ┌─── page layout ─────────────────────┐
+ │ │
+ │ ┌── block "content" ──┐ │
+ │ │ ┌─ block "top" ───┐ │ │
+ │ │ │ │ │ │
+ │ │ └─────────────────┘ │ │
+ │ │ ┌─ block "bottom" ┐ │ │
+ │ │ │ │ │ │
+ │ │ └─────────────────┘ │ │
+ │ └─────────────────────┘ │
+ │ │
+ └─────────────────────────────────────┘
+
+While other pages ("boom" and "baz") share a different content structure -
+two boxes side by side:
+
+.. code-block:: text
+
+ ┌─── page layout ─────────────────────┐
+ │ │
+ │ ┌── block "content" ──┐ │
+ │ │ │ │
+ │ │ ┌ block ┐ ┌ block ┐ │ │
+ │ │ │"left" │ │"right"│ │ │
+ │ │ │ │ │ │ │ │
+ │ │ │ │ │ │ │ │
+ │ │ └───────┘ └───────┘ │ │
+ │ └─────────────────────┘ │
+ │ │
+ └─────────────────────────────────────┘
+
+Without the ``embed`` tag, you have two ways to design your templates:
+
+ * Create two "intermediate" base templates that extend the master layout
+ template: one with vertically stacked boxes to be used by the "foo" and
+ "bar" pages and another one with side-by-side boxes for the "boom" and
+ "baz" pages.
+
+ * Embed the markup for the top/bottom and left/right boxes into each page
+ template directly.
+
+These two solutions do not scale well because they each have a major drawback:
+
+ * The first solution may indeed work for this simplified example. But imagine
+ we add a sidebar, which may again contain different, recurring structures
+ of content. Now we would need to create intermediate base templates for
+ all occurring combinations of content structure and sidebar structure...
+ and so on.
+
+ * The second solution involves duplication of common code with all its negative
+ consequences: any change involves finding and editing all affected copies
+ of the structure, correctness has to be verified for each copy, copies may
+ go out of sync by careless modifications etc.
+
+In such a situation, the ``embed`` tag comes in handy. The common layout
+code can live in a single base template, and the two different content structures,
+let's call them "micro layouts" go into separate templates which are embedded
+as necessary:
+
+Page template ``foo.twig``:
+
+.. code-block:: jinja
+
+ {% extends "layout_skeleton.twig" %}
+
+ {% block content %}
+ {% embed "vertical_boxes_skeleton.twig" %}
+ {% block top %}
+ Some content for the top box
+ {% endblock %}
+
+ {% block bottom %}
+ Some content for the bottom box
+ {% endblock %}
+ {% endembed %}
+ {% endblock %}
+
+And here is the code for ``vertical_boxes_skeleton.twig``:
+
+.. code-block:: html+jinja
+
+
+ {% block top %}
+ Top box default content
+ {% endblock %}
+
+
+The goal of the ``vertical_boxes_skeleton.twig`` template being to factor
+out the HTML markup for the boxes.
+
+The ``embed`` tag takes the exact same arguments as the ``include`` tag:
+
+.. code-block:: jinja
+
+ {% embed "base" with {'foo': 'bar'} %}
+ ...
+ {% endembed %}
+
+ {% embed "base" with {'foo': 'bar'} only %}
+ ...
+ {% endembed %}
+
+ {% embed "base" ignore missing %}
+ ...
+ {% endembed %}
+
+.. warning::
+
+ As embedded templates do not have "names", auto-escaping strategies based
+ on the template "filename" won't work as expected if you change the
+ context (for instance, if you embed a CSS/JavaScript template into an HTML
+ one). In that case, explicitly set the default auto-escaping strategy with
+ the ``autoescape`` tag.
+
+.. seealso:: :doc:`include<../tags/include>`
diff --git a/src/composer/vendor/twig/twig/doc/tags/extends.rst b/src/composer/vendor/twig/twig/doc/tags/extends.rst
new file mode 100644
index 00000000..1ad2b12b
--- /dev/null
+++ b/src/composer/vendor/twig/twig/doc/tags/extends.rst
@@ -0,0 +1,268 @@
+``extends``
+===========
+
+The ``extends`` tag can be used to extend a template from another one.
+
+.. note::
+
+ Like PHP, Twig does not support multiple inheritance. So you can only have
+ one extends tag called per rendering. However, Twig supports horizontal
+ :doc:`reuse
', 1)));
+ $node = new Twig_Node_Spaceless($body, 1);
+
+ $this->assertEquals($body, $node->getNode('body'));
+ }
+
+ public function getTests()
+ {
+ $body = new Twig_Node(array(new Twig_Node_Text('