Skip to content
Commits on Source (4250)
......@@ -12,3 +12,6 @@ indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[composer.json]
indent_size = 4
core/assets/vendor/**/*
core/modules/locale/tests/locale_test.js
core/vendor/**/*
vendor/**/*
sites/**/files/**/*
libraries/**/*
sites/**/libraries/**/*
profiles/**/libraries/**/*
**/js_test_files/**/*
{
"env": {
"browser": true
},
"globals": {
"Drupal": true,
"drupalSettings": true,
"drupalTranslations": true,
"domready": true,
"jQuery": true,
"_": true,
"matchMedia": true,
"Backbone": true,
"Modernizr": true,
"CKEDITOR": true
},
"rules": {
// Errors.
"block-scoped-var": 2,
"brace-style": [2, "stroustrup", {"allowSingleLine": true}],
"comma-style": [2, "last"],
"eqeqeq": [2, "smart"],
"guard-for-in": 2,
"indent": [2, 2, {"indentSwitchCase": true}],
"key-spacing": [2, {"beforeColon": false, "afterColon": true}],
"no-implied-eval": 2,
"no-mixed-spaces-and-tabs": 2,
"no-nested-ternary": 2,
"no-reserved-keys": 2,
"no-trailing-spaces": 2,
"no-undef": 2,
"no-undefined": 2,
"no-unused-vars": [2, {"vars": "local", "args": "none"}],
"semi": [2, "always"],
"space-after-keywords": [2, "always", {"checkFunctionKeyword": true}],
"space-before-blocks": [2, "always"],
"space-in-brackets": [2, "never"],
"space-in-parens": [2, "never"],
"spaced-line-comment": [2, "always"],
"strict": 2,
// Warnings.
"max-nested-callbacks": [1, 3],
// Disabled.
"camelcase": 0,
"consistent-return": 0,
"dot-notation": 0,
"new-cap": 0,
"no-alert": 0,
"no-new": 0,
"no-shadow": 0,
"no-underscore-dangle": 0,
"no-use-before-define": 0,
"quotes": 0
}
"extends": "./core/.eslintrc"
}
# Drupal git normalization
# @see http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
# @see http://drupal.org/node/1542048
# @see https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
# @see https://www.drupal.org/node/1542048
# Normally these settings would be done with macro attributes for improved
# readability and easier maintenance. However macros can only be defined at the
......@@ -16,27 +16,27 @@
# - Deny applying with `git apply --whitespace=error-all`.
# - Fix automatically with `git apply --whitespace=fix`.
# Auto-detect text files, ensure they use LF.
* text=auto eol=lf
*.config text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.css text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.dist text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.engine text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.html text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=html
*.inc text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.info text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.install text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.js text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.json text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.lock text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.map text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.md text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.module text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.php text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.po text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.profile text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.script text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.sh text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.sql text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.test text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.theme text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php
*.twig text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.txt text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.xml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
*.yml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
......@@ -47,6 +47,10 @@
*.gif -text diff
*.gz -text diff
*.ico -text diff
*.jpeg -text diff
*.jpg -text diff
*.png -text diff
*.phar -text diff
*.exe -text diff
*.svgz -text diff
*.ttf -text diff
......@@ -3,7 +3,7 @@
#
# Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig\.save)$">
<FilesMatch "\.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock))$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$">
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
......@@ -15,12 +15,6 @@
# Don't show directory listings for URLs which map to a directory.
Options -Indexes
# Follow symbolic links in this directory.
Options +FollowSymLinks
# Make Drupal handle any 404 errors.
ErrorDocument 404 /index.php
# Set the default handler.
DirectoryIndex index.php index.html index.htm
......@@ -28,17 +22,21 @@ DirectoryIndex index.php index.html index.htm
AddType image/svg+xml svg svgz
AddEncoding gzip svgz
# Override PHP settings that cannot be changed at runtime. See
# Most of the following PHP settings cannot be changed at runtime. See
# sites/default/default.settings.php and
# Drupal\Core\DrupalKernel::bootEnvironment() for settings that can be
# changed at runtime.
# PHP 5, Apache 1 and 2.
<IfModule mod_php5.c>
php_value assert.active 0
php_flag session.auto_start off
php_value mbstring.http_input pass
php_value mbstring.http_output pass
php_flag mbstring.encoding_translation off
# PHP 5.6 has deprecated $HTTP_RAW_POST_DATA and produces warnings if this is
# not set.
php_value always_populate_raw_post_data -1
</IfModule>
# Requires mod_expires to be enabled.
......@@ -59,6 +57,14 @@ AddEncoding gzip svgz
</FilesMatch>
</IfModule>
# Set a fallback resource if mod_rewrite is not enabled. This allows Drupal to
# work without clean URLs. This requires Apache version >= 2.2.16. If Drupal is
# not accessed by the top level URL (i.e.: http://example.com/drupal/ instead of
# http://example.com/), the path to index.php will need to be adjusted.
<IfModule !mod_rewrite.c>
FallbackResource /index.php
</IfModule>
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
......@@ -87,21 +93,21 @@ AddEncoding gzip svgz
# If you do not have mod_rewrite installed, you should remove these
# directories from your webroot or otherwise protect them from being
# downloaded.
RewriteRule "(^|/)\." - [F]
RewriteRule "(^|/)\.(?!well-known)" - [F]
# If your site can be accessed both with and without the 'www.' prefix, you
# can use one of the following settings to redirect users to your preferred
# URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
#
# To redirect all users to access the site WITH the 'www.' prefix,
# (http://example.com/... will be redirected to http://www.example.com/...)
# (http://example.com/foo will be redirected to http://www.example.com/foo)
# uncomment the following:
# RewriteCond %{HTTP_HOST} .
# RewriteCond %{HTTP_HOST} !^www\. [NC]
# RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
#
# To redirect all users to access the site WITHOUT the 'www.' prefix,
# (http://www.example.com/... will be redirected to http://example.com/...)
# (http://www.example.com/foo will be redirected to http://example.com/foo)
# uncomment the following:
# RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
# RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301]
......@@ -122,6 +128,9 @@ AddEncoding gzip svgz
RewriteCond %{REQUEST_URI} !core
RewriteRule ^ %1/core/%2 [L,QSA,R=301]
# Rewrite install.php during installation to see if mod_rewrite is working
RewriteRule ^core/install.php core/install.php?rewrite=ok [QSA,L]
# Pass all requests not referring directly to files in the filesystem to
# index.php.
RewriteCond %{REQUEST_FILENAME} !-f
......@@ -136,14 +145,14 @@ AddEncoding gzip svgz
# Allow access to PHP files in /core (like authorize.php or install.php):
RewriteCond %{REQUEST_URI} !/core/[^/]*\.php$
# Allow access to test-specific PHP files:
RewriteCond %{REQUEST_URI} !/core/modules/system/tests/https?.php$
RewriteCond %{REQUEST_URI} !/core/modules/system/tests/https?.php
# Allow access to Statistics module's custom front controller.
# Copy and adapt this rule to directly execute PHP files in contributed or
# custom modules or to run another PHP application in the same directory.
RewriteCond %{REQUEST_URI} !/core/modules/statistics/statistics.php$
# Deny access to any other PHP files that do not match the rules above.
# Specifically, disallow autoload.php from being served directly.
RewriteRule "^(.+/.*|autoload)\.php$" - [F]
RewriteRule "^(.+/.*|autoload)\.php($|/)" - [F]
# Rules to correctly serve gzip compressed CSS and JS files.
# Requires both mod_rewrite and mod_headers to be enabled.
......@@ -171,8 +180,10 @@ AddEncoding gzip svgz
</IfModule>
</IfModule>
# Add headers to all responses.
# Various header fixes.
<IfModule mod_headers.c>
# Disable content sniffing, since it's an attack vector.
Header always set X-Content-Type-Options nosniff
# Disable Proxy header, since it's an attack vector.
RequestHeader unset Proxy
</IfModule>
......@@ -14,36 +14,36 @@ ABOUT DRUPAL
Drupal is an open source content management platform supporting a variety of
websites ranging from personal weblogs to large community-driven websites. For
more information, see the Drupal website at https://drupal.org/, and join the
Drupal community at https://drupal.org/community.
more information, see the Drupal website at https://www.drupal.org, and join
the Drupal community at https://www.drupal.org/community.
Legal information about Drupal:
* Know your rights when using Drupal:
See LICENSE.txt in the "core" directory.
* Learn about the Drupal trademark and logo policy:
http://drupal.com/trademark
https://www.drupal.com/trademark
CONFIGURATION AND FEATURES
--------------------------
Drupal core (what you get when you download and extract a drupal-x.y.tar.gz or
drupal-x.y.zip file from https://drupal.org/project/drupal) has what you need to
get started with your website. It includes several modules (extensions that add
functionality) for common website features, such as managing content, user
accounts, image uploading, and search. Core comes with many options that allow
site-specific configuration. In addition to the core modules, there are
drupal-x.y.zip file from https://www.drupal.org/project/drupal) has what you
need to get started with your website. It includes several modules (extensions
that add functionality) for common website features, such as managing content,
user accounts, image uploading, and search. Core comes with many options that
allow site-specific configuration. In addition to the core modules, there are
thousands of contributed modules (for functionality not included with Drupal
core) available for download.
More about configuration:
* Install, upgrade, and maintain Drupal:
See INSTALL.txt and UPGRADE.txt in the "core" directory.
* Install, update, and maintain Drupal:
See INSTALL.txt and UPDATE.txt in the "core" directory.
* Learn about how to use Drupal to create your site:
https://drupal.org/documentation
https://www.drupal.org/documentation
* Follow best practices:
https://drupal.org/best-practices
https://www.drupal.org/best-practices
* Download contributed modules to /modules to extend Drupal's functionality:
https://drupal.org/project/modules
https://www.drupal.org/project/modules
* See also: "Developing for Drupal" for writing your own modules, below.
......@@ -68,11 +68,11 @@ the required extensions separately; place the downloaded profile in the
More about installation profiles and distributions:
* Read about the difference between installation profiles and distributions:
https://drupal.org/node/1089736
https://www.drupal.org/node/1089736
* Download contributed installation profiles and distributions:
https://drupal.org/project/distributions
https://www.drupal.org/project/distributions
* Develop your own installation profile or distribution:
https://drupal.org/developing/distributions
https://www.drupal.org/developing/distributions
APPEARANCE
......@@ -85,9 +85,9 @@ custom theme.
More about themes:
* Download contributed themes to /themes to modify Drupal's appearance:
https://drupal.org/project/themes
https://www.drupal.org/project/themes
* Develop your own theme:
https://drupal.org/documentation/theme
https://www.drupal.org/documentation/theme
DEVELOPING FOR DRUPAL
---------------------
......@@ -108,13 +108,13 @@ when nothing existing comes close to what you need.
More about developing:
* Search for existing contributed modules:
https://drupal.org/project/modules
https://www.drupal.org/project/modules
* Contribute a patch:
https://drupal.org/patch/submit
https://www.drupal.org/patch/submit
* Develop your own module:
https://drupal.org/developing/modules
https://www.drupal.org/developing/modules
* Follow programming best practices:
https://drupal.org/developing/best-practices
https://www.drupal.org/developing/best-practices
* Refer to the API documentation:
https://api.drupal.org/api/drupal/8
* Learn from documented Drupal API examples:
......
......@@ -4,11 +4,6 @@
* @file
* Includes the autoloader created by Composer.
*
* This file can be edited to change the autoloader if you are managing a
* project's dependencies using Composer. If Drupal code requires the
* autoloader, it should always be loaded using this file so that projects
* using Composer continue to work.
*
* @see composer.json
* @see index.php
* @see core/install.php
......@@ -16,4 +11,4 @@
* @see core/modules/statistics/statistics.php
*/
return require __DIR__ . '/core/vendor/autoload.php';
return require __DIR__ . '/vendor/autoload.php';
{
"name": "drupal/drupal",
"description": "Drupal is an open source content management platform powering millions of websites and applications.",
"type": "project",
"license": "GPL-2.0+",
"require": {
"composer/installers": "^1.0.20",
"drupal/core": "~8.0"
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"preferred-install": "dist",
"autoloader-suffix": "Drupal8"
},
"extra": {
"_readme": [
"By default Drupal loads the autoloader from ./core/vendor/autoload.php.",
"To change the autoloader you can edit ./autoload.php."
]
}
"name": "drupal/drupal",
"description": "Drupal is an open source content management platform powering millions of websites and applications.",
"type": "project",
"license": "GPL-2.0+",
"require": {
"composer/installers": "^1.0.21",
"wikimedia/composer-merge-plugin": "~1.3"
},
"replace": {
"drupal/core": "~8.2"
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"preferred-install": "dist",
"autoloader-suffix": "Drupal8"
},
"extra": {
"_readme": [
"By default Drupal loads the autoloader from ./vendor/autoload.php.",
"To change the autoloader you can edit ./autoload.php."
],
"merge-plugin": {
"include": [
"core/composer.json"
],
"recurse": false,
"replace": false,
"merge-extra": false
}
},
"autoload": {
"psr-4": {
"Drupal\\Core\\Composer\\": "core/lib/Drupal/Core/Composer"
}
},
"scripts": {
"pre-autoload-dump": "Drupal\\Core\\Composer\\Composer::preAutoloadDump",
"post-autoload-dump": "Drupal\\Core\\Composer\\Composer::ensureHtaccess",
"post-package-install": "Drupal\\Core\\Composer\\Composer::vendorTestCodeCleanup",
"post-package-update": "Drupal\\Core\\Composer\\Composer::vendorTestCodeCleanup"
}
}
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "60f7057617c6d995bf9946d0b12f0b5d",
"packages": [
{
"name": "asm89/stack-cors",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/asm89/stack-cors.git",
"reference": "3ae8ef219bb4c9a6caf857421719aa07fa7776cc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/asm89/stack-cors/zipball/3ae8ef219bb4c9a6caf857421719aa07fa7776cc",
"reference": "3ae8ef219bb4c9a6caf857421719aa07fa7776cc",
"shasum": ""
},
"require": {
"php": ">=5.3.2",
"symfony/http-foundation": "~2.1|~3.0",
"symfony/http-kernel": "~2.1|~3.0"
},
"type": "library",
"autoload": {
"psr-0": {
"Asm89\\Stack": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Alexander",
"email": "iam.asm89@gmail.com"
}
],
"description": "Cross-origin resource sharing library and stack middleware",
"homepage": "https://github.com/asm89/stack-cors",
"keywords": [
"cors",
"stack"
],
"time": "2016-08-01T12:05:04+00:00"
},
{
"name": "composer/installers",
"version": "v1.0.21",
"source": {
"type": "git",
"url": "https://github.com/composer/installers.git",
"reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/installers/zipball/d64e23fce42a4063d63262b19b8e7c0f3b5e4c45",
"reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45",
"shasum": ""
},
"replace": {
"roundcube/plugin-installer": "*",
"shama/baton": "*"
},
"require-dev": {
"composer/composer": "1.0.*@dev",
"phpunit/phpunit": "4.1.*"
},
"type": "composer-installer",
"extra": {
"class": "Composer\\Installers\\Installer",
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-0": {
"Composer\\Installers\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kyle Robinson Young",
"email": "kyle@dontkry.com",
"homepage": "https://github.com/shama"
}
],
"description": "A multi-framework Composer library installer",
"homepage": "http://composer.github.com/installers/",
"keywords": [
"Craft",
"Dolibarr",
"Hurad",
"MODX Evo",
"OXID",
"SMF",
"Thelia",
"WolfCMS",
"agl",
"aimeos",
"annotatecms",
"bitrix",
"cakephp",
"chef",
"codeigniter",
"concrete5",
"croogo",
"dokuwiki",
"drupal",
"elgg",
"fuelphp",
"grav",
"installer",
"joomla",
"kohana",
"laravel",
"lithium",
"magento",
"mako",
"mediawiki",
"modulework",
"moodle",
"phpbb",
"piwik",
"ppi",
"puppet",
"roundcube",
"shopware",
"silverstripe",
"symfony",
"typo3",
"wordpress",
"zend",
"zikula"
],
"time": "2015-02-18T17:17:01+00:00"
},
{
"name": "composer/semver",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
"reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/semver/zipball/d0e1ccc6d44ab318b758d709e19176037da6b1ba",
"reference": "d0e1ccc6d44ab318b758d709e19176037da6b1ba",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "~4.5",
"phpunit/phpunit-mock-objects": "~2.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.1-dev"
}
},
"autoload": {
"psr-4": {
"Composer\\Semver\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Rob Bast",
"email": "rob.bast@gmail.com"
},
{
"name": "Nils Adermann",
"email": "naderman@naderman.de",
"homepage": "http://www.naderman.de"
},
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
}
],
"description": "Semver library that offers utilities, version constraint parsing and validation.",
"keywords": [
"semantic",
"semver",
"validation",
"versioning"
],
"time": "2015-09-21T09:42:36+00:00"
},
{
"name": "doctrine/annotations",
"version": "v1.2.7",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
"reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
"reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
"shasum": ""
},
"require": {
"doctrine/lexer": "1.*",
"php": ">=5.3.2"
},
"require-dev": {
"doctrine/cache": "1.*",
"phpunit/phpunit": "4.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3.x-dev"
}
},
"autoload": {
"psr-0": {
"Doctrine\\Common\\Annotations\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Docblock Annotations Parser",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"annotations",
"docblock",
"parser"
],
"time": "2015-08-31T12:32:49+00:00"
},
{
"name": "doctrine/cache",
"version": "v1.4.2",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/8c434000f420ade76a07c64cbe08ca47e5c101ca",
"reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"phpunit/phpunit": ">=3.7",
"predis/predis": "~1.0",
"satooshi/php-coveralls": "~0.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.5.x-dev"
}
},
"autoload": {
"psr-0": {
"Doctrine\\Common\\Cache\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Caching library offering an object-oriented API for many cache backends",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"cache",
"caching"
],
"time": "2015-08-31T12:36:41+00:00"
},
{
"name": "doctrine/collections",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/collections.git",
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
},
"autoload": {
"psr-0": {
"Doctrine\\Common\\Collections\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Collections Abstraction library",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"array",
"collections",
"iterator"
],
"time": "2015-04-14T22:21:58+00:00"
},
{
"name": "doctrine/common",
"version": "v2.5.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/common.git",
"reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/common/zipball/0009b8f0d4a917aabc971fb089eba80e872f83f9",
"reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9",
"shasum": ""
},
"require": {
"doctrine/annotations": "1.*",
"doctrine/cache": "1.*",
"doctrine/collections": "1.*",
"doctrine/inflector": "1.*",
"doctrine/lexer": "1.*",
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "~3.7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.6.x-dev"
}
},
"autoload": {
"psr-0": {
"Doctrine\\Common\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Common Library for Doctrine projects",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"annotations",
"collections",
"eventmanager",
"persistence",
"spl"
],
"time": "2015-08-31T13:00:22+00:00"
},
{
"name": "doctrine/inflector",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/inflector.git",
"reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/inflector/zipball/0bcb2e79d8571787f18b7eb036ed3d004908e604",
"reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "4.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-0": {
"Doctrine\\Common\\Inflector\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Common String Manipulations with regard to casing and singular/plural rules.",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"inflection",
"pluralize",
"singularize",
"string"
],
"time": "2014-12-20T21:24:13+00:00"
},
{
"name": "doctrine/lexer",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c",
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-0": {
"Doctrine\\Common\\Lexer\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"lexer",
"parser"
],
"time": "2014-09-09T13:34:57+00:00"
},
{
"name": "easyrdf/easyrdf",
"version": "0.9.1",
"source": {
"type": "git",
"url": "https://github.com/njh/easyrdf.git",
"reference": "acd09dfe0555fbcfa254291e433c45fdd4652566"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/njh/easyrdf/zipball/acd09dfe0555fbcfa254291e433c45fdd4652566",
"reference": "acd09dfe0555fbcfa254291e433c45fdd4652566",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"ext-pcre": "*",
"php": ">=5.2.8"
},
"require-dev": {
"phpunit/phpunit": "~3.5",
"sami/sami": "~1.4",
"squizlabs/php_codesniffer": "~1.4.3"
},
"suggest": {
"ml/json-ld": "~1.0"
},
"type": "library",
"autoload": {
"psr-0": {
"EasyRdf_": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Nicholas Humfrey",
"email": "njh@aelius.com",
"homepage": "http://www.aelius.com/njh/",
"role": "Developer"
},
{
"name": "Alexey Zakhlestin",
"email": "indeyets@gmail.com",
"role": "Developer"
}
],
"description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.",
"homepage": "http://www.easyrdf.org/",
"keywords": [
"Linked Data",
"RDF",
"Semantic Web",
"Turtle",
"rdfa",
"sparql"
],
"time": "2015-02-27T09:45:49+00:00"
},
{
"name": "egulias/email-validator",
"version": "1.2.9",
"source": {
"type": "git",
"url": "https://github.com/egulias/EmailValidator.git",
"reference": "af864423f50ea59f96c87bb1eae147a70bcf67a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/af864423f50ea59f96c87bb1eae147a70bcf67a1",
"reference": "af864423f50ea59f96c87bb1eae147a70bcf67a1",
"shasum": ""
},
"require": {
"doctrine/lexer": "~1.0,>=1.0.1",
"php": ">= 5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.4",
"satooshi/php-coveralls": "dev-master"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-0": {
"Egulias\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Eduardo Gulias Davis"
}
],
"description": "A library for validating emails",
"homepage": "https://github.com/egulias/EmailValidator",
"keywords": [
"email",
"emailvalidation",
"emailvalidator",
"validation",
"validator"
],
"time": "2015-06-22T21:07:51+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "6.2.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "3f808fba627f2c5b69e2501217bf31af349c1427"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/3f808fba627f2c5b69e2501217bf31af349c1427",
"reference": "3f808fba627f2c5b69e2501217bf31af349c1427",
"shasum": ""
},
"require": {
"guzzlehttp/promises": "^1.0",
"guzzlehttp/psr7": "^1.3.1",
"php": ">=5.5"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "^4.0",
"psr/log": "^1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.2-dev"
}
},
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle is a PHP HTTP client library",
"homepage": "http://guzzlephp.org/",
"keywords": [
"client",
"curl",
"framework",
"http",
"http client",
"rest",
"web service"
],
"time": "2016-07-15T17:22:37+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "c10d860e2a9595f8883527fa0021c7da9e65f579"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/c10d860e2a9595f8883527fa0021c7da9e65f579",
"reference": "c10d860e2a9595f8883527fa0021c7da9e65f579",
"shasum": ""
},
"require": {
"php": ">=5.5.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "Guzzle promises library",
"keywords": [
"promise"
],
"time": "2016-05-18T16:56:05+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/5c6447c9df362e8f8093bda8f5d8873fe5c7f65b",
"reference": "5c6447c9df362e8f8093bda8f5d8873fe5c7f65b",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
}
],
"description": "PSR-7 message implementation",
"keywords": [
"http",
"message",
"stream",
"uri"
],
"time": "2016-06-24T23:00:38+00:00"
},
{
"name": "ircmaxell/password-compat",
"version": "v1.0.4",
"source": {
"type": "git",
"url": "https://github.com/ircmaxell/password_compat.git",
"reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c",
"reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c",
"shasum": ""
},
"require-dev": {
"phpunit/phpunit": "4.*"
},
"type": "library",
"autoload": {
"files": [
"lib/password.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Anthony Ferrara",
"email": "ircmaxell@php.net",
"homepage": "http://blog.ircmaxell.com"
}
],
"description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
"homepage": "https://github.com/ircmaxell/password_compat",
"keywords": [
"hashing",
"password"
],
"time": "2014-11-20T16:49:30+00:00"
},
{
"name": "masterminds/html5",
"version": "2.2.1",
"source": {
"type": "git",
"url": "https://github.com/Masterminds/html5-php.git",
"reference": "170aa5cb35b29fccafbf5ea63487c013f396fdc9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/170aa5cb35b29fccafbf5ea63487c013f396fdc9",
"reference": "170aa5cb35b29fccafbf5ea63487c013f396fdc9",
"shasum": ""
},
"require": {
"ext-libxml": "*",
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.*",
"sami/sami": "~2.0",
"satooshi/php-coveralls": "1.0.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.1-dev"
}
},
"autoload": {
"psr-4": {
"Masterminds\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Matt Butcher",
"email": "technosophos@gmail.com"
},
{
"name": "Asmir Mustafic",
"email": "goetas@gmail.com"
},
{
"name": "Matt Farina",
"email": "matt@mattfarina.com"
}
],
"description": "An HTML5 parser and serializer.",
"homepage": "http://masterminds.github.io/html5-php",
"keywords": [
"HTML5",
"dom",
"html",
"parser",
"querypath",
"serializer",
"xml"
],
"time": "2016-05-10T14:11:45+00:00"
},
{
"name": "paragonie/random_compat",
"version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "a208865a5aeffc2dbbef2a5b3409887272d93f32"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/a208865a5aeffc2dbbef2a5b3409887272d93f32",
"reference": "a208865a5aeffc2dbbef2a5b3409887272d93f32",
"shasum": ""
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"pseudorandom",
"random"
],
"time": "2015-12-01T02:52:15+00:00"
},
{
"name": "psr/http-message",
"version": "1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2015-05-04T20:22:00+00:00"
},
{
"name": "psr/log",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "1.0.0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/1.0.0",
"reference": "1.0.0",
"shasum": ""
},
"type": "library",
"autoload": {
"psr-0": {
"Psr\\Log\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"keywords": [
"log",
"psr",
"psr-3"
],
"time": "2012-12-21T11:40:51+00:00"
},
{
"name": "stack/builder",
"version": "v1.0.4",
"source": {
"type": "git",
"url": "https://github.com/stackphp/builder.git",
"reference": "59fcc9b448a8ce5e338a04c4e2e4aca893e83425"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/stackphp/builder/zipball/59fcc9b448a8ce5e338a04c4e2e4aca893e83425",
"reference": "59fcc9b448a8ce5e338a04c4e2e4aca893e83425",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"symfony/http-foundation": "~2.1|~3.0",
"symfony/http-kernel": "~2.1|~3.0"
},
"require-dev": {
"silex/silex": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-0": {
"Stack": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Igor Wiedler",
"email": "igor@wiedler.ch"
}
],
"description": "Builder for stack middlewares based on HttpKernelInterface.",
"keywords": [
"stack"
],
"time": "2016-06-02T06:58:42+00:00"
},
{
"name": "symfony-cmf/routing",
"version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony-cmf/Routing.git",
"reference": "b93704ca098334f56e9b317932f21a4362e620db"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/b93704ca098334f56e9b317932f21a4362e620db",
"reference": "b93704ca098334f56e9b317932f21a4362e620db",
"shasum": ""
},
"require": {
"php": "^5.3.9|^7.0",
"psr/log": "1.*",
"symfony/http-kernel": "^2.2|3.*",
"symfony/routing": "^2.2|3.*"
},
"require-dev": {
"friendsofsymfony/jsrouting-bundle": "^1.1",
"symfony-cmf/testing": "^1.3",
"symfony/config": "^2.2|3.*",
"symfony/dependency-injection": "^2.0.5|3.*",
"symfony/event-dispatcher": "^2.1|3.*"
},
"suggest": {
"symfony/event-dispatcher": "DynamicRouter can optionally trigger an event at the start of matching. Minimal version (~2.1)"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Cmf\\Component\\Routing\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Symfony CMF Community",
"homepage": "https://github.com/symfony-cmf/Routing/contributors"
}
],
"description": "Extends the Symfony2 routing component for dynamic routes and chaining several routers",
"homepage": "http://cmf.symfony.com",
"keywords": [
"database",
"routing"
],
"time": "2016-03-31T09:11:39+00:00"
},
{
"name": "symfony/class-loader",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/class-loader.git",
"reference": "7c46951128f7169cbece2c303fba4a9eb35cbe68"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/class-loader/zipball/7c46951128f7169cbece2c303fba4a9eb35cbe68",
"reference": "7c46951128f7169cbece2c303fba4a9eb35cbe68",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/polyfill-apcu": "~1.1"
},
"require-dev": {
"symfony/finder": "~2.0,>=2.0.5|~3.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\ClassLoader\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony ClassLoader Component",
"homepage": "https://symfony.com",
"time": "2017-01-10T14:03:07+00:00"
},
{
"name": "symfony/console",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/2e18b8903d9c498ba02e1dfa73f64d4894bb6912",
"reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/debug": "~2.7,>=2.7.2|~3.0.0",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/event-dispatcher": "~2.1|~3.0.0",
"symfony/process": "~2.1|~3.0.0"
},
"suggest": {
"psr/log": "For using the console logger",
"symfony/event-dispatcher": "",
"symfony/process": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Console\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2017-01-08T20:43:03+00:00"
},
{
"name": "symfony/debug",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "567681e2c4e5431704e884e4be25a95fd900770f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/567681e2c4e5431704e884e4be25a95fd900770f",
"reference": "567681e2c4e5431704e884e4be25a95fd900770f",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"psr/log": "~1.0"
},
"conflict": {
"symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
},
"require-dev": {
"symfony/class-loader": "~2.2|~3.0.0",
"symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Debug\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/dependency-injection",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
"reference": "b75356611675364607d697f314850d9d870a84aa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b75356611675364607d697f314850d9d870a84aa",
"reference": "b75356611675364607d697f314850d9d870a84aa",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"conflict": {
"symfony/expression-language": "<2.6"
},
"require-dev": {
"symfony/config": "~2.2|~3.0.0",
"symfony/expression-language": "~2.6|~3.0.0",
"symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7"
},
"suggest": {
"symfony/config": "",
"symfony/expression-language": "For using expressions in service container configuration",
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\DependencyInjection\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
"time": "2017-01-10T14:27:01+00:00"
},
{
"name": "symfony/event-dispatcher",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "74877977f90fb9c3e46378d5764217c55f32df34"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/74877977f90fb9c3e46378d5764217c55f32df34",
"reference": "74877977f90fb9c3e46378d5764217c55f32df34",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~2.0,>=2.0.5|~3.0.0",
"symfony/dependency-injection": "~2.6|~3.0.0",
"symfony/expression-language": "~2.6|~3.0.0",
"symfony/stopwatch": "~2.3|~3.0.0"
},
"suggest": {
"symfony/dependency-injection": "",
"symfony/http-kernel": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\EventDispatcher\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/http-foundation",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "464cdde6757a40701d758112cc7ff2c6adf6e82f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/464cdde6757a40701d758112cc7ff2c6adf6e82f",
"reference": "464cdde6757a40701d758112cc7ff2c6adf6e82f",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.1",
"symfony/polyfill-php54": "~1.0",
"symfony/polyfill-php55": "~1.0"
},
"require-dev": {
"symfony/expression-language": "~2.4|~3.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\HttpFoundation\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
"time": "2017-01-08T20:43:03+00:00"
},
{
"name": "symfony/http-kernel",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
"reference": "1097eb4ce0a7bdcd030f110c123682fed89a137c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/1097eb4ce0a7bdcd030f110c123682fed89a137c",
"reference": "1097eb4ce0a7bdcd030f110c123682fed89a137c",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"psr/log": "~1.0",
"symfony/debug": "~2.6,>=2.6.2",
"symfony/event-dispatcher": "~2.6,>=2.6.7|~3.0.0",
"symfony/http-foundation": "~2.7.20|~2.8.13|~3.1.6"
},
"conflict": {
"symfony/config": "<2.7"
},
"require-dev": {
"symfony/browser-kit": "~2.3|~3.0.0",
"symfony/class-loader": "~2.1|~3.0.0",
"symfony/config": "~2.8",
"symfony/console": "~2.3|~3.0.0",
"symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
"symfony/dependency-injection": "~2.8|~3.0.0",
"symfony/dom-crawler": "~2.0,>=2.0.5|~3.0.0",
"symfony/expression-language": "~2.4|~3.0.0",
"symfony/finder": "~2.0,>=2.0.5|~3.0.0",
"symfony/process": "~2.0,>=2.0.5|~3.0.0",
"symfony/routing": "~2.8|~3.0.0",
"symfony/stopwatch": "~2.3|~3.0.0",
"symfony/templating": "~2.2|~3.0.0",
"symfony/translation": "~2.0,>=2.0.5|~3.0.0",
"symfony/var-dumper": "~2.6|~3.0.0"
},
"suggest": {
"symfony/browser-kit": "",
"symfony/class-loader": "",
"symfony/config": "",
"symfony/console": "",
"symfony/dependency-injection": "",
"symfony/finder": "",
"symfony/var-dumper": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\HttpKernel\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
"time": "2017-01-12T20:27:24+00:00"
},
{
"name": "symfony/polyfill-apcu",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-apcu.git",
"reference": "5d4474f447403c3348e37b70acc2b95475b7befa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/5d4474f447403c3348e37b70acc2b95475b7befa",
"reference": "5d4474f447403c3348e37b70acc2b95475b7befa",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
},
"autoload": {
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting apcu_* functions to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"apcu",
"compatibility",
"polyfill",
"portable",
"shim"
],
"time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-iconv",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git",
"reference": "cba36f3616d9866b3e52662e88da5c090fac1e97"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/cba36f3616d9866b3e52662e88da5c090fac1e97",
"reference": "cba36f3616d9866b3e52662e88da5c090fac1e97",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-iconv": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Iconv\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Iconv extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"iconv",
"polyfill",
"portable",
"shim"
],
"time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
"reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-php54",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php54.git",
"reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/90e085822963fdcc9d1c5b73deb3d2e5783b16a0",
"reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php54\\": ""
},
"files": [
"bootstrap.php"
],
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/polyfill-php55",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php55.git",
"reference": "03e3f0350bca2220e3623a0e340eef194405fc67"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/03e3f0350bca2220e3623a0e340eef194405fc67",
"reference": "03e3f0350bca2220e3623a0e340eef194405fc67",
"shasum": ""
},
"require": {
"ircmaxell/password-compat": "~1.0",
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php55\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/process",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "ebb3c2abe0940a703f08e0cbe373f62d97d40231"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/ebb3c2abe0940a703f08e0cbe373f62d97d40231",
"reference": "ebb3c2abe0940a703f08e0cbe373f62d97d40231",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Process\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/psr-http-message-bridge",
"version": "v0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/psr-http-message-bridge.git",
"reference": "dc7e308e1dc2898a46776e2221a643cb08315453"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/dc7e308e1dc2898a46776e2221a643cb08315453",
"reference": "dc7e308e1dc2898a46776e2221a643cb08315453",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"psr/http-message": "~1.0",
"symfony/http-foundation": "~2.3|~3.0"
},
"require-dev": {
"symfony/phpunit-bridge": "~2.7|~3.0"
},
"suggest": {
"zendframework/zend-diactoros": "To use the Zend Diactoros factory"
},
"type": "symfony-bridge",
"autoload": {
"psr-4": {
"Symfony\\Bridge\\PsrHttpMessage\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "PSR HTTP message bridge",
"homepage": "http://symfony.com",
"keywords": [
"http",
"http-message",
"psr-7"
],
"time": "2015-05-29T17:57:12+00:00"
},
{
"name": "symfony/routing",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
"reference": "2a7e3e02bbfb0a4f722e6a3154489e4ac8b3a97f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/2a7e3e02bbfb0a4f722e6a3154489e4ac8b3a97f",
"reference": "2a7e3e02bbfb0a4f722e6a3154489e4ac8b3a97f",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"conflict": {
"symfony/config": "<2.7"
},
"require-dev": {
"doctrine/annotations": "~1.0",
"doctrine/common": "~2.2",
"psr/log": "~1.0",
"symfony/config": "~2.7|~3.0.0",
"symfony/expression-language": "~2.4|~3.0.0",
"symfony/http-foundation": "~2.3|~3.0.0",
"symfony/yaml": "~2.0,>=2.0.5|~3.0.0"
},
"suggest": {
"doctrine/annotations": "For using the annotation loader",
"symfony/config": "For using the all-in-one router or any loader",
"symfony/dependency-injection": "For loading routes from a service",
"symfony/expression-language": "For using expression matching",
"symfony/http-foundation": "For using a Symfony Request object",
"symfony/yaml": "For using the YAML loader"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Routing\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Routing Component",
"homepage": "https://symfony.com",
"keywords": [
"router",
"routing",
"uri",
"url"
],
"time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/serializer",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/serializer.git",
"reference": "3a5337e3daaabb9ada73d60f3271adb6bfa56a1a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/serializer/zipball/3a5337e3daaabb9ada73d60f3271adb6bfa56a1a",
"reference": "3a5337e3daaabb9ada73d60f3271adb6bfa56a1a",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/polyfill-php55": "~1.0"
},
"require-dev": {
"doctrine/annotations": "~1.0",
"doctrine/cache": "~1.0",
"symfony/config": "~2.2|~3.0.0",
"symfony/property-access": "~2.3|~3.0.0",
"symfony/yaml": "~2.0,>=2.0.5|~3.0.0"
},
"suggest": {
"doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
"doctrine/cache": "For using the default cached annotation reader and metadata cache.",
"symfony/config": "For using the XML mapping loader.",
"symfony/property-access": "For using the ObjectNormalizer.",
"symfony/yaml": "For using the default YAML mapping loader."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Serializer\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Serializer Component",
"homepage": "https://symfony.com",
"time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/translation",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "b4ac4a393f6970cc157fba17be537380de396a86"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/b4ac4a393f6970cc157fba17be537380de396a86",
"reference": "b4ac4a393f6970cc157fba17be537380de396a86",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
"symfony/config": "<2.7"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~2.8",
"symfony/intl": "~2.4|~3.0.0",
"symfony/yaml": "~2.2|~3.0.0"
},
"suggest": {
"psr/log": "To use logging capability in translator",
"symfony/config": "",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Translation\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
"time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/validator",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/validator.git",
"reference": "3b1a3188efea75ec7c0419a2568b6e5f82031811"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/validator/zipball/3b1a3188efea75ec7c0419a2568b6e5f82031811",
"reference": "3b1a3188efea75ec7c0419a2568b6e5f82031811",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.0",
"symfony/translation": "~2.4|~3.0.0"
},
"require-dev": {
"doctrine/annotations": "~1.0",
"doctrine/cache": "~1.0",
"egulias/email-validator": "~1.2,>=1.2.1",
"symfony/config": "~2.2|~3.0.0",
"symfony/expression-language": "~2.4|~3.0.0",
"symfony/http-foundation": "~2.3|~3.0.0",
"symfony/intl": "~2.7.4|~2.8|~3.0.0",
"symfony/property-access": "~2.3|~3.0.0",
"symfony/yaml": "~2.0,>=2.0.5|~3.0.0"
},
"suggest": {
"doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
"doctrine/cache": "For using the default cached annotation reader and metadata cache.",
"egulias/email-validator": "Strict (RFC compliant) email validation",
"symfony/config": "",
"symfony/expression-language": "For using the 2.4 Expression validator",
"symfony/http-foundation": "",
"symfony/intl": "",
"symfony/property-access": "For using the 2.4 Validator API",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Validator\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Validator Component",
"homepage": "https://symfony.com",
"time": "2017-01-12T19:24:25+00:00"
},
{
"name": "symfony/yaml",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2",
"reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2017-01-03T13:49:52+00:00"
},
{
"name": "twig/twig",
"version": "v1.24.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8",
"reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8",
"shasum": ""
},
"require": {
"php": ">=5.2.7"
},
"require-dev": {
"symfony/debug": "~2.7",
"symfony/phpunit-bridge": "~2.7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.24-dev"
}
},
"autoload": {
"psr-0": {
"Twig_": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com",
"role": "Project Founder"
},
{
"name": "Twig Team",
"homepage": "http://twig.sensiolabs.org/contributors",
"role": "Contributors"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
"homepage": "http://twig.sensiolabs.org",
"keywords": [
"templating"
],
"time": "2016-01-25T21:22:18+00:00"
},
{
"name": "wikimedia/composer-merge-plugin",
"version": "v1.3.1",
"source": {
"type": "git",
"url": "https://github.com/wikimedia/composer-merge-plugin.git",
"reference": "0bdf8543d445ee067c9ba7d5d4a5dde70b9785f4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/0bdf8543d445ee067c9ba7d5d4a5dde70b9785f4",
"reference": "0bdf8543d445ee067c9ba7d5d4a5dde70b9785f4",
"shasum": ""
},
"require": {
"composer-plugin-api": "^1.0",
"php": ">=5.3.2"
},
"require-dev": {
"composer/composer": "1.0.*@dev",
"jakub-onderka/php-parallel-lint": "~0.8",
"phpunit/phpunit": "~4.8|~5.0",
"squizlabs/php_codesniffer": "~2.1.0"
},
"type": "composer-plugin",
"extra": {
"branch-alias": {
"dev-master": "1.3.x-dev"
},
"class": "Wikimedia\\Composer\\MergePlugin"
},
"autoload": {
"psr-4": {
"Wikimedia\\Composer\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Bryan Davis",
"email": "bd808@wikimedia.org"
}
],
"description": "Composer plugin to merge multiple composer.json files",
"time": "2016-03-08T17:11:37+00:00"
},
{
"name": "zendframework/zend-diactoros",
"version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-diactoros.git",
"reference": "e2f5c12916c74da384058d0dfbc7fbc0b03d1181"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/e2f5c12916c74da384058d0dfbc7fbc0b03d1181",
"reference": "e2f5c12916c74da384058d0dfbc7fbc0b03d1181",
"shasum": ""
},
"require": {
"php": ">=5.4",
"psr/http-message": "~1.0"
},
"provide": {
"psr/http-message-implementation": "~1.0.0"
},
"require-dev": {
"phpunit/phpunit": "~4.6",
"squizlabs/php_codesniffer": "^2.3.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev",
"dev-develop": "1.1-dev"
}
},
"autoload": {
"psr-4": {
"Zend\\Diactoros\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-2-Clause"
],
"description": "PSR HTTP Message implementations",
"homepage": "https://github.com/zendframework/zend-diactoros",
"keywords": [
"http",
"psr",
"psr-7"
],
"time": "2015-08-10T20:04:20+00:00"
},
{
"name": "zendframework/zend-escaper",
"version": "2.5.1",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-escaper.git",
"reference": "a4b227d8a477f4e7e9073f8e0a7ae7dbd3104a73"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/a4b227d8a477f4e7e9073f8e0a7ae7dbd3104a73",
"reference": "a4b227d8a477f4e7e9073f8e0a7ae7dbd3104a73",
"shasum": ""
},
"require": {
"php": ">=5.3.23"
},
"require-dev": {
"fabpot/php-cs-fixer": "1.7.*",
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.5-dev",
"dev-develop": "2.6-dev"
}
},
"autoload": {
"psr-4": {
"Zend\\Escaper\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"homepage": "https://github.com/zendframework/zend-escaper",
"keywords": [
"escaper",
"zf2"
],
"time": "2015-06-03T14:05:37+00:00"
},
{
"name": "zendframework/zend-feed",
"version": "2.5.2",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-feed.git",
"reference": "0661345b82b51428619e05d3aadd3de65b57fa54"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-feed/zipball/0661345b82b51428619e05d3aadd3de65b57fa54",
"reference": "0661345b82b51428619e05d3aadd3de65b57fa54",
"shasum": ""
},
"require": {
"php": ">=5.5",
"zendframework/zend-escaper": "~2.5",
"zendframework/zend-stdlib": "~2.5"
},
"require-dev": {
"fabpot/php-cs-fixer": "1.7.*",
"phpunit/phpunit": "~4.0",
"zendframework/zend-cache": "~2.5",
"zendframework/zend-db": "~2.5",
"zendframework/zend-http": "~2.5",
"zendframework/zend-servicemanager": "~2.5",
"zendframework/zend-validator": "~2.5"
},
"suggest": {
"zendframework/zend-cache": "Zend\\Cache component",
"zendframework/zend-db": "Zend\\Db component",
"zendframework/zend-http": "Zend\\Http for PubSubHubbub, and optionally for use with Zend\\Feed\\Reader",
"zendframework/zend-servicemanager": "Zend\\ServiceManager component, for default/recommended ExtensionManager implementations",
"zendframework/zend-validator": "Zend\\Validator component"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.5-dev",
"dev-develop": "2.6-dev"
}
},
"autoload": {
"psr-4": {
"Zend\\Feed\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"description": "provides functionality for consuming RSS and Atom feeds",
"homepage": "https://github.com/zendframework/zend-feed",
"keywords": [
"feed",
"zf2"
],
"time": "2015-08-04T21:39:18+00:00"
},
{
"name": "zendframework/zend-hydrator",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-hydrator.git",
"reference": "f3ed8b833355140350bbed98d8a7b8b66875903f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-hydrator/zipball/f3ed8b833355140350bbed98d8a7b8b66875903f",
"reference": "f3ed8b833355140350bbed98d8a7b8b66875903f",
"shasum": ""
},
"require": {
"php": ">=5.5",
"zendframework/zend-stdlib": "^2.5.1"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "^2.0@dev",
"zendframework/zend-eventmanager": "^2.5.1",
"zendframework/zend-filter": "^2.5.1",
"zendframework/zend-inputfilter": "^2.5.1",
"zendframework/zend-serializer": "^2.5.1",
"zendframework/zend-servicemanager": "^2.5.1"
},
"suggest": {
"zendframework/zend-eventmanager": "^2.5.1, to support aggregate hydrator usage",
"zendframework/zend-filter": "^2.5.1, to support naming strategy hydrator usage",
"zendframework/zend-serializer": "^2.5.1, to use the SerializableStrategy",
"zendframework/zend-servicemanager": "^2.5.1, to support hydrator plugin manager usage"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev",
"dev-develop": "1.1-dev"
}
},
"autoload": {
"psr-4": {
"Zend\\Hydrator\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"homepage": "https://github.com/zendframework/zend-hydrator",
"keywords": [
"hydrator",
"zf2"
],
"time": "2015-09-17T14:06:43+00:00"
},
{
"name": "zendframework/zend-stdlib",
"version": "2.7.3",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-stdlib.git",
"reference": "8ac0c77ff567fcf49b58689ee3bfa7595be102bc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/8ac0c77ff567fcf49b58689ee3bfa7595be102bc",
"reference": "8ac0c77ff567fcf49b58689ee3bfa7595be102bc",
"shasum": ""
},
"require": {
"php": ">=5.5",
"zendframework/zend-hydrator": "~1.0"
},
"require-dev": {
"athletic/athletic": "~0.1",
"fabpot/php-cs-fixer": "1.7.*",
"phpunit/phpunit": "~4.0",
"zendframework/zend-config": "~2.5",
"zendframework/zend-eventmanager": "~2.5",
"zendframework/zend-filter": "~2.5",
"zendframework/zend-inputfilter": "~2.5",
"zendframework/zend-serializer": "~2.5",
"zendframework/zend-servicemanager": "~2.5"
},
"suggest": {
"zendframework/zend-eventmanager": "To support aggregate hydrator usage",
"zendframework/zend-filter": "To support naming strategy hydrator usage",
"zendframework/zend-serializer": "Zend\\Serializer component",
"zendframework/zend-servicemanager": "To support hydrator plugin manager usage"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.7-dev",
"dev-develop": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Zend\\Stdlib\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"homepage": "https://github.com/zendframework/zend-stdlib",
"keywords": [
"stdlib",
"zf2"
],
"time": "2015-09-25T04:06:33+00:00"
}
],
"packages-dev": [
{
"name": "behat/mink",
"version": "v1.7.1",
"source": {
"type": "git",
"url": "https://github.com/minkphp/Mink.git",
"reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/minkphp/Mink/zipball/e6930b9c74693dff7f4e58577e1b1743399f3ff9",
"reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9",
"shasum": ""
},
"require": {
"php": ">=5.3.1",
"symfony/css-selector": "~2.1|~3.0"
},
"require-dev": {
"symfony/phpunit-bridge": "~2.7|~3.0"
},
"suggest": {
"behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)",
"behat/mink-goutte-driver": "fast headless driver for any app without JS emulation",
"behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)",
"behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.7.x-dev"
}
},
"autoload": {
"psr-4": {
"Behat\\Mink\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Konstantin Kudryashov",
"email": "ever.zet@gmail.com",
"homepage": "http://everzet.com"
}
],
"description": "Browser controller/emulator abstraction for PHP",
"homepage": "http://mink.behat.org/",
"keywords": [
"browser",
"testing",
"web"
],
"time": "2016-03-05T08:26:18+00:00"
},
{
"name": "behat/mink-browserkit-driver",
"version": "v1.3.2",
"source": {
"type": "git",
"url": "https://github.com/minkphp/MinkBrowserKitDriver.git",
"reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/10e67fb4a295efcd62ea0bf16025a85ea19534fb",
"reference": "10e67fb4a295efcd62ea0bf16025a85ea19534fb",
"shasum": ""
},
"require": {
"behat/mink": "^1.7.1@dev",
"php": ">=5.3.6",
"symfony/browser-kit": "~2.3|~3.0",
"symfony/dom-crawler": "~2.3|~3.0"
},
"require-dev": {
"silex/silex": "~1.2",
"symfony/phpunit-bridge": "~2.7|~3.0"
},
"type": "mink-driver",
"extra": {
"branch-alias": {
"dev-master": "1.3.x-dev"
}
},
"autoload": {
"psr-4": {
"Behat\\Mink\\Driver\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Konstantin Kudryashov",
"email": "ever.zet@gmail.com",
"homepage": "http://everzet.com"
}
],
"description": "Symfony2 BrowserKit driver for Mink framework",
"homepage": "http://mink.behat.org/",
"keywords": [
"Mink",
"Symfony2",
"browser",
"testing"
],
"time": "2016-03-05T08:59:47+00:00"
},
{
"name": "behat/mink-goutte-driver",
"version": "v1.2.1",
"source": {
"type": "git",
"url": "https://github.com/minkphp/MinkGoutteDriver.git",
"reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/8b9ad6d2d95bc70b840d15323365f52fcdaea6ca",
"reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca",
"shasum": ""
},
"require": {
"behat/mink": "~1.6@dev",
"behat/mink-browserkit-driver": "~1.2@dev",
"fabpot/goutte": "~1.0.4|~2.0|~3.1",
"php": ">=5.3.1"
},
"require-dev": {
"symfony/phpunit-bridge": "~2.7|~3.0"
},
"type": "mink-driver",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
},
"autoload": {
"psr-4": {
"Behat\\Mink\\Driver\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Konstantin Kudryashov",
"email": "ever.zet@gmail.com",
"homepage": "http://everzet.com"
}
],
"description": "Goutte driver for Mink framework",
"homepage": "http://mink.behat.org/",
"keywords": [
"browser",
"goutte",
"headless",
"testing"
],
"time": "2016-03-05T09:04:22+00:00"
},
{
"name": "doctrine/instantiator",
"version": "1.0.5",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
"reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
"reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
"shasum": ""
},
"require": {
"php": ">=5.3,<8.0-DEV"
},
"require-dev": {
"athletic/athletic": "~0.1.8",
"ext-pdo": "*",
"ext-phar": "*",
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
"homepage": "http://ocramius.github.com/"
}
],
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
"homepage": "https://github.com/doctrine/instantiator",
"keywords": [
"constructor",
"instantiate"
],
"time": "2015-06-14T21:17:01+00:00"
},
{
"name": "fabpot/goutte",
"version": "v3.1.2",
"source": {
"type": "git",
"url": "https://github.com/FriendsOfPHP/Goutte.git",
"reference": "3cbc6ed222422a28400e470050f14928a153207e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/3cbc6ed222422a28400e470050f14928a153207e",
"reference": "3cbc6ed222422a28400e470050f14928a153207e",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^6.0",
"php": ">=5.5.0",
"symfony/browser-kit": "~2.1|~3.0",
"symfony/css-selector": "~2.1|~3.0",
"symfony/dom-crawler": "~2.1|~3.0"
},
"type": "application",
"extra": {
"branch-alias": {
"dev-master": "3.1-dev"
}
},
"autoload": {
"psr-4": {
"Goutte\\": "Goutte"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "A simple PHP Web Scraper",
"homepage": "https://github.com/FriendsOfPHP/Goutte",
"keywords": [
"scraper"
],
"time": "2015-11-05T12:58:44+00:00"
},
{
"name": "jcalderonzumba/gastonjs",
"version": "v1.0.2",
"source": {
"type": "git",
"url": "https://github.com/jcalderonzumba/gastonjs.git",
"reference": "21bebb8ca03eb0f93ec2f3fad61192fb079e2622"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jcalderonzumba/gastonjs/zipball/21bebb8ca03eb0f93ec2f3fad61192fb079e2622",
"reference": "21bebb8ca03eb0f93ec2f3fad61192fb079e2622",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "~5.0|~6.0",
"php": ">=5.4"
},
"require-dev": {
"phpunit/phpunit": "~4.6",
"silex/silex": "~1.2",
"symfony/phpunit-bridge": "~2.7",
"symfony/process": "~2.1"
},
"type": "phantomjs-api",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Zumba\\GastonJS\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Juan Francisco Calderón Zumba",
"email": "juanfcz@gmail.com",
"homepage": "http://github.com/jcalderonzumba"
}
],
"description": "PhantomJS API based server for webpage automation",
"homepage": "https://github.com/jcalderonzumba/gastonjs",
"keywords": [
"api",
"automation",
"browser",
"headless",
"phantomjs"
],
"time": "2016-01-18T09:21:03+00:00"
},
{
"name": "jcalderonzumba/mink-phantomjs-driver",
"version": "v0.3.1",
"source": {
"type": "git",
"url": "https://github.com/jcalderonzumba/MinkPhantomJSDriver.git",
"reference": "782892dbea4af7d04024374672b3790b6c008def"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jcalderonzumba/MinkPhantomJSDriver/zipball/782892dbea4af7d04024374672b3790b6c008def",
"reference": "782892dbea4af7d04024374672b3790b6c008def",
"shasum": ""
},
"require": {
"behat/mink": "~1.6",
"jcalderonzumba/gastonjs": "~1.0",
"php": ">=5.4",
"twig/twig": "~1.20|~2.0"
},
"require-dev": {
"phpunit/phpunit": "~4.6",
"silex/silex": "~1.2",
"symfony/css-selector": "~2.1",
"symfony/phpunit-bridge": "~2.7",
"symfony/process": "~2.3"
},
"type": "mink-driver",
"extra": {
"branch-alias": {
"dev-master": "0.4.x-dev"
}
},
"autoload": {
"psr-4": {
"Zumba\\Mink\\Driver\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Juan Francisco Calderón Zumba",
"email": "juanfcz@gmail.com",
"homepage": "http://github.com/jcalderonzumba"
}
],
"description": "PhantomJS driver for Mink framework",
"homepage": "http://mink.behat.org/",
"keywords": [
"ajax",
"browser",
"headless",
"javascript",
"phantomjs",
"testing"
],
"time": "2015-12-04T13:55:02+00:00"
},
{
"name": "mikey179/vfsStream",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/mikey179/vfsStream.git",
"reference": "73bcb605b741a7d5044b47592338c633788b0eb7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mikey179/vfsStream/zipball/73bcb605b741a7d5044b47592338c633788b0eb7",
"reference": "73bcb605b741a7d5044b47592338c633788b0eb7",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "~4.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.6.x-dev"
}
},
"autoload": {
"psr-0": {
"org\\bovigo\\vfs\\": "src/main/php"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Frank Kleine",
"homepage": "http://frankkleine.de/",
"role": "Developer"
}
],
"description": "Virtual file system to mock the real file system in unit tests.",
"homepage": "http://vfs.bovigo.org/",
"time": "2015-10-06T16:59:57+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
"version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"suggest": {
"dflydev/markdown": "~1.0",
"erusev/parsedown": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-0": {
"phpDocumentor": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mike van Riel",
"email": "mike.vanriel@naenius.com"
}
],
"time": "2015-02-03T12:10:50+00:00"
},
{
"name": "phpspec/prophecy",
"version": "v1.5.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7",
"reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"phpdocumentor/reflection-docblock": "~2.0",
"sebastian/comparator": "~1.1"
},
"require-dev": {
"phpspec/phpspec": "~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4.x-dev"
}
},
"autoload": {
"psr-0": {
"Prophecy\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Konstantin Kudryashov",
"email": "ever.zet@gmail.com",
"homepage": "http://everzet.com"
},
{
"name": "Marcello Duarte",
"email": "marcello.duarte@gmail.com"
}
],
"description": "Highly opinionated mocking framework for PHP 5.3+",
"homepage": "https://github.com/phpspec/prophecy",
"keywords": [
"Double",
"Dummy",
"fake",
"mock",
"spy",
"stub"
],
"time": "2015-08-13T10:07:40+00:00"
},
{
"name": "phpunit/php-code-coverage",
"version": "2.2.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
"reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"phpunit/php-file-iterator": "~1.3",
"phpunit/php-text-template": "~1.2",
"phpunit/php-token-stream": "~1.3",
"sebastian/environment": "^1.3.2",
"sebastian/version": "~1.0"
},
"require-dev": {
"ext-xdebug": ">=2.1.4",
"phpunit/phpunit": "~4"
},
"suggest": {
"ext-dom": "*",
"ext-xdebug": ">=2.2.1",
"ext-xmlwriter": "*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.2.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
"homepage": "https://github.com/sebastianbergmann/php-code-coverage",
"keywords": [
"coverage",
"testing",
"xunit"
],
"time": "2015-10-06T15:47:00+00:00"
},
{
"name": "phpunit/php-file-iterator",
"version": "1.4.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
"reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
"reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
"homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
"keywords": [
"filesystem",
"iterator"
],
"time": "2015-06-21T13:08:43+00:00"
},
{
"name": "phpunit/php-text-template",
"version": "1.2.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-text-template.git",
"reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
"reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "Simple template engine.",
"homepage": "https://github.com/sebastianbergmann/php-text-template/",
"keywords": [
"template"
],
"time": "2015-06-21T13:50:34+00:00"
},
{
"name": "phpunit/php-timer",
"version": "1.0.7",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
"reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
"reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Utility class for timing",
"homepage": "https://github.com/sebastianbergmann/php-timer/",
"keywords": [
"timer"
],
"time": "2015-06-21T08:01:12+00:00"
},
{
"name": "phpunit/php-token-stream",
"version": "1.4.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
"reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Wrapper around PHP's tokenizer extension.",
"homepage": "https://github.com/sebastianbergmann/php-token-stream/",
"keywords": [
"tokenizer"
],
"time": "2015-09-15T10:49:45+00:00"
},
{
"name": "phpunit/phpunit",
"version": "4.8.28",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "558a3a0d28b4cb7e4a593a4fbd2220e787076225"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/558a3a0d28b4cb7e4a593a4fbd2220e787076225",
"reference": "558a3a0d28b4cb7e4a593a4fbd2220e787076225",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-json": "*",
"ext-pcre": "*",
"ext-reflection": "*",
"ext-spl": "*",
"php": ">=5.3.3",
"phpspec/prophecy": "^1.3.1",
"phpunit/php-code-coverage": "~2.1",
"phpunit/php-file-iterator": "~1.4",
"phpunit/php-text-template": "~1.2",
"phpunit/php-timer": "^1.0.6",
"phpunit/phpunit-mock-objects": "~2.3",
"sebastian/comparator": "~1.1",
"sebastian/diff": "~1.2",
"sebastian/environment": "~1.3",
"sebastian/exporter": "~1.2",
"sebastian/global-state": "~1.0",
"sebastian/version": "~1.0",
"symfony/yaml": "~2.1|~3.0"
},
"suggest": {
"phpunit/php-invoker": "~1.1"
},
"bin": [
"phpunit"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.8.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "The PHP Unit Testing framework.",
"homepage": "https://phpunit.de/",
"keywords": [
"phpunit",
"testing",
"xunit"
],
"time": "2016-11-14T06:25:28+00:00"
},
{
"name": "phpunit/phpunit-mock-objects",
"version": "2.3.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
"reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
"reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": ">=5.3.3",
"phpunit/php-text-template": "~1.2",
"sebastian/exporter": "~1.2"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"suggest": {
"ext-soap": "*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"role": "lead"
}
],
"description": "Mock Object library for PHPUnit",
"homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
"keywords": [
"mock",
"xunit"
],
"time": "2015-10-02T06:51:40+00:00"
},
{
"name": "sebastian/comparator",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
"reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"sebastian/diff": "~1.2",
"sebastian/exporter": "~1.2"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Volker Dusch",
"email": "github@wallbash.com"
},
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Provides the functionality to compare PHP values for equality",
"homepage": "http://www.github.com/sebastianbergmann/comparator",
"keywords": [
"comparator",
"compare",
"equality"
],
"time": "2015-07-26T15:48:44+00:00"
},
{
"name": "sebastian/diff",
"version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
"reference": "863df9687835c62aa423a22412d26fa2ebde3fd3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3",
"reference": "863df9687835c62aa423a22412d26fa2ebde3fd3",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Kore Nordmann",
"email": "mail@kore-nordmann.de"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Diff implementation",
"homepage": "http://www.github.com/sebastianbergmann/diff",
"keywords": [
"diff"
],
"time": "2015-02-22T15:13:53+00:00"
},
{
"name": "sebastian/environment",
"version": "1.3.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
"reference": "6324c907ce7a52478eeeaede764f48733ef5ae44"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44",
"reference": "6324c907ce7a52478eeeaede764f48733ef5ae44",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Provides functionality to handle HHVM/PHP environments",
"homepage": "http://www.github.com/sebastianbergmann/environment",
"keywords": [
"Xdebug",
"environment",
"hhvm"
],
"time": "2015-08-03T06:14:51+00:00"
},
{
"name": "sebastian/exporter",
"version": "1.2.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "7ae5513327cb536431847bcc0c10edba2701064e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
"reference": "7ae5513327cb536431847bcc0c10edba2701064e",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"sebastian/recursion-context": "~1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Volker Dusch",
"email": "github@wallbash.com"
},
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
{
"name": "Adam Harvey",
"email": "aharvey@php.net"
}
],
"description": "Provides the functionality to export PHP variables for visualization",
"homepage": "http://www.github.com/sebastianbergmann/exporter",
"keywords": [
"export",
"exporter"
],
"time": "2015-06-21T07:55:53+00:00"
},
{
"name": "sebastian/global-state",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
"reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01",
"reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.2"
},
"suggest": {
"ext-uopz": "*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
}
],
"description": "Snapshotting of global state",
"homepage": "http://www.github.com/sebastianbergmann/global-state",
"keywords": [
"global state"
],
"time": "2014-10-06T09:23:50+00:00"
},
{
"name": "sebastian/recursion-context",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
"reference": "994d4a811bafe801fb06dccbee797863ba2792ba"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba",
"reference": "994d4a811bafe801fb06dccbee797863ba2792ba",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
},
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
{
"name": "Adam Harvey",
"email": "aharvey@php.net"
}
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
"time": "2015-06-21T08:04:50+00:00"
},
{
"name": "sebastian/version",
"version": "1.0.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/version.git",
"reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
"reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
"shasum": ""
},
"type": "library",
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
"time": "2015-06-21T13:59:46+00:00"
},
{
"name": "symfony/browser-kit",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
"reference": "d2a5de15c8341a470a66becf4597bc675686a72b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/d2a5de15c8341a470a66becf4597bc675686a72b",
"reference": "d2a5de15c8341a470a66becf4597bc675686a72b",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/dom-crawler": "~2.1|~3.0.0"
},
"require-dev": {
"symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
"symfony/process": "~2.3.34|~2.7,>=2.7.6|~3.0.0"
},
"suggest": {
"symfony/process": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\BrowserKit\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
"time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/css-selector",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "f45daea42232d9ca5cf561ec64f0d4aea820877f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/f45daea42232d9ca5cf561ec64f0d4aea820877f",
"reference": "f45daea42232d9ca5cf561ec64f0d4aea820877f",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\CssSelector\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jean-François Simon",
"email": "jeanfrancois.simon@sensiolabs.com"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2017-01-02T20:30:24+00:00"
},
{
"name": "symfony/dom-crawler",
"version": "v2.8.16",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
"reference": "52cc211afa9458c0a54c478010a55f44892c1c02"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/52cc211afa9458c0a54c478010a55f44892c1c02",
"reference": "52cc211afa9458c0a54c478010a55f44892c1c02",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
"symfony/css-selector": "~2.8|~3.0.0"
},
"suggest": {
"symfony/css-selector": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\DomCrawler\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"time": "2017-01-02T20:30:24+00:00"
}
],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": [],
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
"php": ">=5.5.9"
},
"platform-dev": []
}
{
"extends": "eslint:recommended",
"env": {
"browser": true
},
"globals": {
"Drupal": true,
"drupalSettings": true,
"drupalTranslations": true,
"domready": true,
"jQuery": true,
"_": true,
"matchMedia": true,
"Backbone": true,
"Modernizr": true,
"CKEDITOR": true
},
"rules": {
// Errors.
"array-bracket-spacing": [2, "never"],
"block-scoped-var": 2,
"brace-style": [2, "stroustrup", {"allowSingleLine": true}],
"comma-dangle": [2, "never"],
"comma-spacing": 2,
"comma-style": [2, "last"],
"computed-property-spacing": [2, "never"],
"curly": [2, "all"],
"eol-last": 2,
"eqeqeq": [2, "smart"],
"guard-for-in": 2,
"indent": [2, 2, {"SwitchCase": 1}],
"key-spacing": [2, {"beforeColon": false, "afterColon": true}],
"keyword-spacing": [2, {"before": true, "after": true}],
"linebreak-style": [2, "unix"],
"lines-around-comment": [2, {"beforeBlockComment": true, "afterBlockComment": false}],
"new-parens": 2,
"no-array-constructor": 2,
"no-caller": 2,
"no-catch-shadow": 2,
"no-eval": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-extra-parens": [2, "functions"],
"no-implied-eval": 2,
"no-iterator": 2,
"no-label-var": 2,
"no-labels": 2,
"no-lone-blocks": 2,
"no-loop-func": 2,
"no-multi-spaces": 2,
"no-multi-str": 2,
"no-native-reassign": 2,
"no-nested-ternary": 2,
"no-new-func": 2,
"no-new-object": 2,
"no-new-wrappers": 2,
"no-octal-escape": 2,
"no-process-exit": 2,
"no-proto": 2,
"no-return-assign": 2,
"no-script-url": 2,
"no-sequences": 2,
"no-shadow-restricted-names": 2,
"no-spaced-func": 2,
"no-trailing-spaces": 2,
"no-undef-init": 2,
"no-undefined": 2,
"no-unused-expressions": 2,
"no-unused-vars": [2, {"vars": "all", "args": "none"}],
"no-with": 2,
"object-curly-spacing": [2, "never"],
"one-var": [2, "never"],
"quote-props": [2, "consistent-as-needed"],
"quotes": [2, "single", "avoid-escape"],
"semi": [2, "always"],
"semi-spacing": [2, {"before": false, "after": true}],
"space-before-blocks": [2, "always"],
"space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
"space-in-parens": [2, "never"],
"space-infix-ops": 2,
"space-unary-ops": [2, { "words": true, "nonwords": false }],
"spaced-comment": [2, "always"],
"strict": [2, "function"],
"yoda": [2, "never"],
// Warnings.
"max-nested-callbacks": [1, 3],
"valid-jsdoc": [1, {
"prefer": {
"returns": "return",
"property": "prop"
},
"requireReturn": false
}]
}
}
# SimpleTest breaks with the following files, so avoid adding them.
vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php
vendor/symfony/class-loader/Symfony/Component/ClassLoader/Tests/Fixtures/php5.4/traits.php
vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services11.php
# The resources for the Validator component are not required.
vendor/symfony/validator/Symfony/Component/Validator/Resources
# Symfony Validator depends on Symfony Translation but only requires the
# TranslatorInterface. Thus, we add only the required interface from Symfony
# Translation by ignoring everything except the interface.
vendor/symfony/translation/Symfony/Component/Translation/*
!vendor/symfony/translation/Symfony/Component/Translation/TranslatorInterface.php
# PHPUnit provides some binary dependencies that are already available.
vendor/phpunit/phpunit/build/dependencies
Drupal 8.0, xxxx-xx-xx (development version)
----------------------
- Added Twig as the default template engine and converted all .tpl.php templates
to .html.twig.
- Added tour module. Provides highly contextual tips for UI elements.
- Improved entity system.
* Added support for saving and deleting entities through the controller.
* Entities are now classed objects, implementing EntityInterface.
* Drupal now understands the concept of a "default" revision, tracked
independently from the latest revision, allowing for the creation of
drafts while the current revision stays published.
* All entity types, not just nodes, now have support for revisions.
- Replaced the core routing system with one built on the Symfony2 framework.
- Configuration:
* Added a centralized file-based configuration system.
* Allows module authors to provide configuration in a standard format.
* Implements functionality to get, set, add and remove configuration.
* Includes ability to override configuration values with language variants
and other runtime values.
- Added the CKEditor WYSIWYG editor. Provides a drag-and-drop configuration UI.
- Included the HTML5 Shiv library to support HTML5 elements in IE 8 and below.
Drupal 8.2.8, 2017-04-19
------------------------
- Fixed security issues. See SA-CORE-2017-002.
Drupal 8.2.7, 2017-03-15
------------------------
- Fixed security issues. See SA-CORE-2017-001.
Drupal 8.2.3, 2016-11-16
------------------------
- Fixed security issues. See SA-CORE-2016-005.
Drupal 8.2.0, 2016-10-05
------------------------
- Updated the git repository configuration to not normalize line endings for
files of unknown type.
- Added vendor libraries:
* Added Stack/Cors 1.0.0.
- Updated vendor libraries:
* Updated to jQuery 2.2.3.
* Updated to Twig 1.24.
* Updated to CKEditor 4.5.11.
* Updated to Symfony Routing 1.4.0.
* Updated to Stack/Builder 1.0.4.
* Updated to Guzzle 6.2.1.
- Added modules:
* Added the Place Block module (experimental) to place a block on any page
without having to navigate to the backend administration form.
* Added the Settings Tray module (experimental) to edit the configuration of
any block on the page. Its machine name in this release is "outside_in".
* Added the Content Moderation module (experimental) to define and use
workflow states such as Draft, Archived and Published. This functionality
was previously provided by the contributed module Workbench Moderation.
* Added the Datetime Range module (experimental) that provides a new field
type with support for start and end dates.
- Raised stability levels of experimental modules:
* Updated the BigPipe module from alpha to beta.
* See https://www.drupal.org/core/experimental#versions for more
information about the stability levels of experimental modules.
- Improved authoring features:
* Relative URLs are automatically converted to absolute ones when content
is output to an RSS feed.
* Enabled revisions by default on new node types.
* Added a redirect option to site-wide contact forms.
* Whenever a new entity is created, a link to it is now provided in a
status message, for easy access to it regardless of the form workflow.
* Styled CKEditor dialogs to match Drupal dialogs.
- Improved site administration experience:
* Numerous improvements to user interface text.
- Improved site building features:
* Added the ability to remove a module's content entities prior to
uninstallation.
* Made it possible to select the comment view mode in the formatter form.
* Fixed the Migrate module to skip over migration sources that require
code from uninstalled modules.
- Improved REST API and decoupled site features:
* Added support for reading (GET) configuration entities as REST resources.
* Added dedicated resources for user login, logout and registration.
* Added support for selecting an authentication provider as part of the
configuration of a REST Export Views Display.
* Added a cors.config service parameter for enabling and configuring
cross-origin resource sharing (CORS).
* Simplified REST configuration with per-resource configuration entities
and less verbose configuration structure. (The previous, advanced
configuration structure is also still supported.)
* Improved the response messages and status codes for requests with missing
or incorrect headers.
* Improved responses to PATCH requests to entity resources to contain the
updated entity in the response body.
- Improved developer APIs:
* Added support for specifying the field item delta as part of an entity
query condition. This was possible in Drupal 7 via
EntityFieldQuery::fieldDeltaCondition(), but missing from earlier
versions of Drupal 8.
- Improved performance/scalability:
* In the internal page cache, 404 responses are now cached for a shorter
time (1 hour by default), to consume less space.
* Breadcrumbs are now cached by the parent of the path rather than the full
path, for fewer cache entries and higher cache hit rates.
- Changed coding standards:
* Local variables and parameters can now use camelCase.
* A blank line is now required after the <?php opening tag.
- Testing improvements:
* Increased feature parity of BrowserTestBase with WebTestBase, including a
deprecated AssertLegacyTrait for easier conversions.
* Converted all kernel tests to the PHPUnit-based kernel test API.
* Improved error reporting for all PHPUnit tests (including unit, kernel,
browser, and JavaScript tests).
Drupal 8.1.0, 2016-04-20
------------------------
- Removed Composer-managed vendor from the git repository:
* Drupal.org packager adds dependencies to zip and tar package. This can be
used without any further steps.
* When not using zip / tar files, e.g. when using a git clone, run composer
install to get dependencies.
* See https://www.drupal.org/documentation/install/download#git
for instructions.
- Added vendor libraries:
* Added Symfony Polyfill Iconv 1.1.0.
* Added paragonie/random_compat 1.4.1.
- Updated vendor libraries:
* Updated to the last 2.x minor version of Symfony: 2.8 (2.8.4).
* Updated to CKEditor 4.5.8.
* Updated to Modernizr 3.3.1.
- Added modules:
* Added the Migrate Drupal UI module (experimental) to provide a UI for
migrating content and configuration from Drupal 6 and Drupal 7.
* Added the BigPipe module (experimental) to improve perceived performance.
- Improved authoring features:
* Enabled browsers' (native) spell checker in CKEditor.
* Added language toolbar button in CKEditor for identifying the language of
text parts.
- Improved site administration experience:
* Improved admin/help page to be more flexible and list tours on it.
- Improved site building features:
* Added a "Rendered entity" field handler in Views.
- Improved distribution building features:
* Added support for distributions to specify an installation language.
- Improved developer APIs:
* Added local ID and revision fields to HAL web service output.
* Added support for image toolkits to be defined with plugin derivatives,
reducing the code needed to extend them.
* Simplified Migrate API by replacing migration configuration entities with
migration plugins.
* Various improvements for defining entity types:
* Added support for entity types to specify translatable plural labels.
* Added a revision log interface and trait for revisionable entity types.
* Added key field definitions to ContentEntityBase, reducing code from
child classes.
* Added generic route providers for add-page and add-form entity routes,
reducing the code needed to define an entity type.
- Testing improvements:
* Added support for automated JavaScript testing.
* Added verbose output for BrowserTestBase.
* Improved reporting of PHPUnit results.
Drupal 8.0.0, 2015-11-19
------------------------
- Significantly improved the front end:
* Made all built-in themes responsive.
* Added support for responsive images.
* Made built-in tables responsive with three levels of column importance.
* Added Twig as the default template engine and converted all .tpl.php
templates and theme functions to .html.twig.
* Removed the PHPTemplate engine.
* Several large scale cleanups of the markup produced by Drupal.
* Added Classy as a base theme to maintain CSS classes and wrappers.
* Added Stable as the default base theme to maintain backwards compatibility
for core template and CSS changes, because templates and CSS outside
Stable can be improved in minor releases (8.1.0, 8.2.0, etc.).
* Redesigned several key elements of the Seven theme.
* Added support for HTML5 elements.
* Included Backbone.js and Underscore.js JavaScript frameworks.
* Updated to jQuery 2.1.4.
* Updated to jQuery UI 1.11.4.
* Removed jquery.bbq.
* Removed the Garland theme from core.
* Removed the Overlay module from core and replaced it with a simple,
dynamic "Back to site" link.
* Improved the asset library system to manage CSS and JavaScript files and
their dependencies. Allowing for smaller AJAX request payloads.
* jQuery is no longer loaded on all pages, only when another asset needs it.
* No JavaScript is loaded at all for anonymous users by default, for faster
page loads.
* Implemented SMACSS-style categorization for CSS files.
* Removed most support for Internet Explorer 8 and below.
* Added Modernizr for making styling changes based on browser support.
* All page template variables converted to blocks (title, breadcrumb,
branding, etc).
* Added the Breakpoint module to manage breakpoints of responsive designs.
* Introduced native Schema.org output in pages.
* Made use of semantic HTML 5 tags when possible. This also makes form input
on mobile devices much easier for users.
* Redesigned icons to look good on high resolution (retina) displays too.
- Made the site administration experience simpler:
* Redesigned the installer.
* Visually updated and extended the Seven (administration) theme.
* Made the administration toolbar responsive and touch friendly.
* Added search to the module listing and made the page easier to read.
* Added the tour module to provide highly contextual tips for UI elements.
- Improved the entity system:
* Added a full CRUD API for entities.
* Improved the field API and entity query API.
* Added support for widgets, formatters, and translation to base entity
fields (such as labels).
* Made view modes configurable for reusable display variants.
* Introduced form modes for reusable form variants.
* Added ability to handle a "default" revision that may not be the latest.
* All content entity types (custom blocks, terms, comments, etc.), not just
nodes, have support for revisions.
* Database schema of content entities is automatically generated based on
entity type and field definitions.
- Added the Typed Data system to manage complex types.
- Refactored routing system based on Symfony2 components.
- Made declarative information (libraries, permissions, routes etc.) use YAML
files for definitions instead of PHP.
- Improved the menu handling systems:
* Moved custom menu item handling to its own module.
* Reworked menu links, local actions, and local tasks based upon the new
routing system.
- Added plugin system to standardize implementation of several core APIs.
- Introduced a new configuration management system:
* Added a centralized configuration system with export and import
functionality.
* Allowed module authors to provide configuration in a YAML file format.
* Implemented functionality to get, set, add, and remove configuration.
* Provided the ability to override configuration values with language
variants and other runtime values.
* Added configuration schema, dependencies, and validation to maintain
data integrity between deployments and updates.
* Support added for both global configuration and configuration entities.
- Improved authoring experience:
* Redesigned the content creation and editing form.
* Content preview is now displayed on the frontend.
* Added the CKEditor WYSIWYG editor. Clean markup guaranteed thanks to tight
integration with the filter system.
* Made uploading, aligning, and captioning of images possible in the editor.
* Modernized the default text formats.
* Added a drag-and-drop configuration UI, which automatically updates the
HTML filter settings, making configuring text formats trivial for typical
use cases.
* Added align and caption filters that can be applied to any element:
images, blockquotes, code snippets, videos…
* Made possible to in-place edit any entity: nodes, blocks…
* Added the Text Editor module to help map other editors to text formats.
- Improved media management:
* Added ability to configure when unused files get deleted with the option
to keep them, useful for media libraries.
* Added a customizable view under the content administration screen that
lists all files uploaded on the system.
* Made uploads immediate when selecting files in file fields.
* Added ability to upload multiple files at once.
* Added local image input filter, to enable secure image posting.
- Included the following Symfony2 components:
* ClassLoader - PSR-0-compatible autoload routines.
* DependencyInjection - Flexible dependency injection container.
......@@ -28,49 +241,45 @@ Drupal 8.0, xxxx-xx-xx (development version)
* Process - Allows for executing commands in a sub-process.
* Routing - Framework for mapping incoming requests to controller
information.
* Serialization - Serialize complex nested objects into JSON/XML etc.
* Validator - Ensure that an object is in a valid state based upon some
validation rules defined for it.
* Yaml - Parser for YAML files.
- Included the Assetic asset management framework for PHP.
- Included Backbone.js and Underscore.js JavaScript frameworks.
- Support added for making HTTP requests through a proxy server.
- Added routing component from Symfony CMF.
- Added Guzzle HTTP library.
- Added Zend Feed component.
- Removed modules from core.
* The following modules have been removed from core, because contributed
modules with similar functionality are available:
* Blog
* Dashboard
* OpenID
* PHP Filter
* Poll
* Profile
* Trigger
- Removed the Overlay module from core.
- Removed the Garland theme from core.
- Removed the Statistics module's accesslog functionality and reports from core.
- Removed the Statistics module's accesslog functionality and reports.
- Removed XML-RPC functionality from core.
- Removed user signatures support from core.
- Removed backwards-compatibility with 'magic_quotes_gpc'/'magic_quotes_runtime'
PHP configuration settings. Both are required to be disabled.
- Universally Unique IDentifier (UUID):
* Support for generating and validating UUIDs.
- JavaScript changes:
* Updated to jQuery 2.1.0
* Updated to jQuery UI 1.10.2
* Removed jquery.bbq
- Tremendously improved language support all around.
- Added ability to generate and validate Universally Unique IDentifiers (UUIDs).
- Tremendously improved language support all around:
* Great language improvements for users:
* Improved language selection with user preference detection in the
installer.
installer based on browser settings.
* The installer is presented in the user's native language.
* Moved base language support to Language module.
* Greatly simplified the interface for setting up languages.
* Improved browser language detection considerably.
* Language domain and path prefix configuraton simplified and centralized;
path prefix detection is now default.
* Language domain and path prefix configuration simplified and
centralized; path prefix detection is now default.
* Added HTML 5 language markup; language information added in markup in
several more places.
* Made it possible to assign external language codes to local languages.
* Introduced the possibility of an administration-specific language
preference for users.
* Language selection fallback language is now independently configurable
without needing to change the site default language.
* Simplified and added new features in interface translation:
* Made interface translation directly accessible from language list.
* Made interface translation directly accessible from the language list.
* Centralized interface translation import to one directory.
* Drupal can now be translated to English and English can be deleted.
* Much improved built-in translation interface.
......@@ -79,6 +288,7 @@ Drupal 8.0, xxxx-xx-xx (development version)
be identified and protected from translation update overwrites.
* All Gettext files are now imported in chunks, better for low resource
environments.
* Automated import and update of translations in the installer and later.
* Improved content language support:
* Made it possible to assign language to taxonomy terms, vocabularies,
menu items, and files.
......@@ -96,39 +306,100 @@ Drupal 8.0, xxxx-xx-xx (development version)
* Added language selectors to most configuration options (views, menus,
etc.)
* Added a configuration translation user interface that works with any
configuration with translatable values (blocks, views, fields, etc).
configuration with translatable values (blocks, views, fields, etc.).
* Added language options to block visibility.
* Much improved language APIs for developers:
* Added simple APIs and hooks to save/delete/update languages.
* New Language class wraps language information, used universally.
* Unified database schemas and APIs to make it easier to spot where
language codes are referenced.
* Made the language negotiation system APIs more consistent for
developers.
* Made it possible for users to have a preferred language separate from
their user entity language.
* The text formatter from t() is now available as format_string().
* The text formatter from t() is now available as FormattableMarkup.
* Added support for interface translation contexts in Drupal.t(),
Drupal.formatPlural() as well as routing, tabs, actions, and contextual
links.
Drupal.formatPlural() as well as routing, tabs, actions, shipped
menu items and contextual links.
* Removed textgroups support from interface translation in favor of
native configuration language support.
* Added configuration schema system to support generating translation
forms for any configuration.
* Reworked Gettext PO support to use pluggable read/write handlers.
* Added language select form element in the Form API.
- Added Email field type to core.
- Added Link field type to core.
- Added Phone number field type to core.
- Added local image input filter, to enable secure image posting.
- Added Views and Views UI module to core.
- Added Entity Reference field type to core.
- Added Date field type to core.
* Added a transliteration API. (Only used for machine names in core.)
* Added a language fallback capability to the interface translation API.
- New field types added to core:
* Email
* Link
* Telephone number
* Entity reference
* Date
- Made commenting more flexible:
* Added the notion of comment types (for reviews, greetings, and so on),
each of which can be configured with a different set of fields.
* Made commenting a field to allow comment threads on entity types other
than nodes.
- Added Views and Views UI module to core:
* Added simple bulk operations functionality to Views.
* Converted various core listings to views, including /node,
/admin/content/node, /admin/people, and several blocks.
* Built in REST API support.
* Rewrote caching integration for better performance.
* Made it possible to configure responsive tables in Views.
- Greatly improved block management:
* Made custom blocks fieldable, revisionable, and translatable entities.
* Added the notion of custom block types.
* Added the ability to place the same block in multiple locations.
* Introduced a block library with categorized blocks.
- Introduced an accessible modal API based on improvements made in collaboration
with the jQuery UI team.
- Made it possible to add fields to contact forms allowing site-builders to
easily build custom forms for soliciting feedback from users.
- Added a Web Services module package.
* Added a RESTful web services provider module.
* Added a serialization module using the Symfony serialization component.
* Added a Hypertext Application Language (HAL) serialization module.
* Added a HTTP Basic authentication provider module.
- Improved performance/scalability significantly:
* Introduced cache tags, which allow content to be invalidated accurately
and instantly, including for reverse proxies and CDNs.
* Added cache contexts, which allow content to be cached correctly, and
placeholdered to improve cache hit rates.
* Implemented cacheability bubbling, which allows strict tracking of assets
and cacheability throughout page rendering.
* Factored out page caching to its own module and enabled it by default.
* Added the Dynamic Page Cache module for authenticated page caching and
enabled it by default.
* Added APCu, memory, and PHP file caching backends to core, alongside
support for a chained, consistent cache backend to support correctly using
fast local cache implementations with multiple web servers.
- Removed support for MyISAM, when using MySQL.
- Testing improvements
* Added PHPUnit for proper unit testing, see
https://phpunit.de/manual/4.8/en/index.html so you can run tests via
your IDE.
* Added BrowserTestBase as an alternative to simpletest for browser
testing (JavaScript support to be included in the future)
* Added KernelTestBase to provide a fast API testing of integration of
different components
* Core branch nightly tests include PHP 5.5, 5.6, 7, sqlite and PostgreSQL.
- Added the migrate module (experimental) with support for migrating content and
configuration from earlier Drupal versions.
- Introduced support for Composer.
- Moved the automated cron execution functionality to its own module.
- Refactored IP address based banning functionality to its own module.
- Security improvements:
* Removed PHP filter, including the ability to use PHP for block visibility.
* Managing fields for each entity type is now a separate permission.
* PDO drivers other than MySQL are now limited to executing single
statements to limit SQL injection vectors.
* Added an autoescape API to prevent cross-site scripting in many of the
places where Drupal outputs HTML.
* Hardened user session and session ID handling.
* Automated CSRF protection in route definitions.
* Clickjacking protection enabled by default.
* Made the core JavaScript API compatible with Content Security Policy
(CSP).
* Trusted host patterns enforced for requests preventing cache and link
poisoning.
- Switched to semantic versioning with significant updates planned every 6
months in 8.1, 8.2, etc.
- Numerous other important changes and additions. See
https://www.drupal.org/list-changes/drupal for a detailed list.
- Numerous bug fixes.
- Numerous API documentation improvements.
- Additional automated test coverage.
Drupal 7.0, 2011-01-05
----------------------
......@@ -207,7 +478,7 @@ Drupal 7.0, 2011-01-05
- Improved time zone support:
* Drupal now uses PHP's time zone database when rendering dates in local
time. Site-wide and user-configured time zone offsets have been converted
to time zone names, e.g. Africa/Abidjan.
to time zone names; for example, Africa/Abidjan.
* In some cases the upgrade and install scripts do not choose the preferred
site default time zone. The automatically-selected time zone can be
corrected at admin/config/regional/settings.
......@@ -233,16 +504,17 @@ Drupal 7.0, 2011-01-05
are available.
- OpenID:
* Added support for Gmail and Google Apps for Domain identifiers. Users can
now login with their user@example.com identifier when example.com is powered
by Google.
now log in with their user@example.com identifier when example.com is
powered by Google.
* Made the OpenID module more pluggable.
- Added code registry:
* Using the registry, modules declare their includable files via their .info file,
allowing Drupal to lazy-load classes and interfaces as needed.
- Theme system:
* Removed the Bluemarine, Chameleon and Pushbutton themes. These themes live
on as contributed themes (http://drupal.org/project/bluemarine,
http://drupal.org/project/chameleon and http://drupal.org/project/pushbutton).
on as contributed themes (https://www.drupal.org/project/bluemarine,
https://www.drupal.org/project/chameleon and
https://www.drupal.org/project/pushbutton).
* Added Stark theme to make analyzing Drupal's default HTML and CSS easier.
* Added Seven as the default administration theme.
* Variable preprocessing of theme hooks prior to template rendering now goes
......@@ -264,7 +536,7 @@ Drupal 7.0, 2011-01-05
preserved but renamed to file_unmanaged_*().
* Rewrote file handling to use PHP stream wrappers to enable support for
both public and private files and to support pluggable storage mechanisms
and access to remote resources (e.g. S3 storage or Flickr photos).
and access to remote resources (for example, S3 storage or Flickr photos).
* The mime_extension_mapping variable has been removed. Modules that need to
alter the default MIME type extension mappings should implement
hook_file_mimetype_mapping_alter().
......@@ -441,13 +713,13 @@ Drupal 6.0, 2008-02-13
- Added support for triggering configurable actions.
- Added the Update status module to automatically check for available updates
and warn sites if they are missing security updates or newer versions.
Sites deploying from CVS should use http://drupal.org/project/cvs_deploy.
Advanced settings provided by http://drupal.org/project/update_advanced.
Sites deploying from CVS should use https://www.drupal.org/project/cvs_deploy.
Advanced settings provided by https://www.drupal.org/project/update_advanced.
- Upgraded the core JavaScript library to jQuery version 1.2.3.
- Added a new Schema API, which provides built-in support for core and
contributed modules to work with databases other than MySQL.
- Removed drupal.module. The functionality lives on as the Site network
contributed module (http://drupal.org/project/site_network).
contributed module (https://www.drupal.org/project/site_network).
- Removed old system updates. Updates from Drupal versions prior to 5.x will
require upgrading to 5.x before upgrading to 6.x.
......@@ -586,7 +858,7 @@ Drupal 4.7.9, 2007-12-05
- fixed a security issue (SQL injection), see SA-2007-031
Drupal 4.7.8, 2007-10-17
----------------------
------------------------
- fixed a security issue (HTTP response splitting), see SA-2007-024
- fixed a security issue (Cross site scripting via uploads), see SA-2007-026
- fixed a security issue (API handling of unpublished comment), see SA-2007-030
......@@ -681,7 +953,7 @@ Drupal 4.7.0, 2006-05-01
- Added support for PHP5's 'mysqli' extension.
- Search module:
* Made indexer smarter and more robust.
* Added advanced search operators (e.g. phrase, node type, ...).
* Added advanced search operators (phrase, node type, etc.).
* Added customizable result ranking.
- PostgreSQL support:
* Removed dependency on PL/pgSQL procedural language.
......@@ -699,7 +971,7 @@ Drupal 4.6.11, 2007-01-05
- Fixed security issue (DoS), see SA-2007-002
Drupal 4.6.10, 2006-10-18
------------------------
-------------------------
- Fixed security issue (XSS), see SA-2006-024
- Fixed security issue (CSRF), see SA-2006-025
- Fixed security issue (Form action attribute injection), see SA-2006-026
......@@ -839,7 +1111,7 @@ Drupal 4.5.0, 2004-10-18
- Syndication:
* Added support for RSS ping-notifications of http://technorati.com/.
* Refactored the categorization of syndicated news items.
* Added an URL alias for 'rss.xml'.
* Added a URL alias for 'rss.xml'.
* Improved date parsing.
- Database backend:
* Added support for multiple database connections.
......@@ -1058,7 +1330,7 @@ Drupal 4.0.0, 2002-06-15
* Made each cloud site have its own settings.
* Modules and themes can now be enabled/disabled using the administration pages.
* Added URL abstraction for links.
* Usability changes (renamed links, better UI, etc).
* Usability changes (renamed links, better UI, etc.).
- Collaboratively revised and expanded the Drupal documentation.
Drupal 3.0.1, 2001-10-15
......
......@@ -18,16 +18,16 @@ Drupal requires:
- A web server with PHP support, for example:
- Apache 2.0 (or greater) (http://httpd.apache.org/).
- Nginx 1.1 (or greater) (http://nginx.com/).
- PHP 5.4.5 (or greater) (http://php.net/). For better security support its
- PHP 5.5.9 (or greater) (http://php.net/). For better security support it is
recommended to update to at least 5.5.21 or 5.6.5.
- One of the following databases:
- MySQL 5.0.15 (or greater) (http://www.mysql.com/).
- MariaDB 5.1.44 (or greater) (https://mariadb.org/). MariaDB is a fully
- MySQL 5.5.3 (or greater) (http://www.mysql.com/).
- MariaDB 5.5.20 (or greater) (https://mariadb.org/). MariaDB is a fully
compatible drop-in replacement for MySQL.
- Percona Server 5.1.70 (or greater) (http://www.percona.com/). Percona
- Percona Server 5.5.8 (or greater) (http://www.percona.com/). Percona
Server is a backwards-compatible replacement for MySQL.
- PostgreSQL 8.3 (or greater) (http://www.postgresql.org/).
- SQLite 3.4.2 (or greater) (http://www.sqlite.org/).
- PostgreSQL 9.1.2 (or greater) (http://www.postgresql.org/).
- SQLite 3.7.11 (or greater) (http://www.sqlite.org/).
For more detailed information about Drupal requirements, including a list of
PHP extensions and configurations that are required, see "System requirements"
......@@ -88,7 +88,20 @@ INSTALLATION
directory within your web server's document root or your public HTML
directory, continue with this command:
mv drupal-x.y.z/* drupal-x.y.z/.htaccess drupal-x.y.z/.csslintrc drupal-x.y.z/.editorconfig drupal-x.y.z/.eslintignore drupal-x.y.z/.eslintrc /path/to/your/installation
mv drupal-x.y.z/* drupal-x.y.z/.htaccess drupal-x.y.z/.csslintrc drupal-x.y.z/.editorconfig drupal-x.y.z/.eslintignore drupal-x.y.z/.eslintrc drupal-x.y.z/.gitattributes /path/to/your/installation
You can also download the latest version of Drupal using Git on the command
line and set up a repository by following the instructions at
https://www.drupal.org/project/drupal/git-instructions for "Setting up
repository for the first time".
Once you have downloaded Drupal successfully, you may install Composer
globally using the instructions at
https://getcomposer.org/doc/00-intro.md#globally
With Composer installed, run the following command from the Drupal web root:
composer install
2. Create the Drupal database.
......@@ -121,60 +134,63 @@ INSTALLATION
a. Missing files directory.
The install script will attempt to create a file storage directory in
the default location at sites/default/files (the location of the files
The install script will attempt to create a public file storage directory
in the default location at sites/default/files (the location of the files
directory may be changed after Drupal is installed).
If auto-creation fails, you can make it work by changing permissions on
the sites/default directory so that the web server can create the files
directory within it for you. (If you are creating a multisite
installation, substitute the correct sites directory for sites/default;
see the Multisite Configuration section of this file, below.)
If auto-creation fails, you can create the directory yourself. (If you are
creating a multisite installation, substitute the correct sites directory
for sites/default; see the Multisite Configuration section of this file,
below.) Sample commands from a Unix/Linux command line:
For example, on a Unix/Linux command line, you can grant everyone
mkdir sites/default/files
chmod a+w sites/default/files
Alternatively, you can make the install script work by changing
permissions on the sites/default directory. The web server can then
create the files directory within it for you.
For example, on a Unix/Linux command line, you can you can grant everyone
(including the web server) permission to write to the sites/default
directory with this command:
chmod a+w sites/default
Be sure to set the permissions back after the installation is finished!
Sample command:
Then re-run install.php (e.g. by clicking "try again" at the bottom of
the Requirements problem page. Once the files directory is created, you
will need to grant everyone (including the web server) permission to
write to it with this command:
chmod go-w sites/default
chmod a+w sites/default/files
Alternatively, instead of allowing the web server to create the files
directory for you as described above, you can create it yourself. Sample
commands from a Unix/Linux command line:
Be sure to set the permissions for the default directory back after the
installation is finished! (Leave the files directory writeable.)
Sample command:
mkdir sites/default/files
chmod a+w sites/default/files
chmod go-w sites/default
b. Missing settings file.
Drupal will try to automatically create settings.php and services.yml
files, which are normally in the directory sites/default (to avoid
problems when upgrading, Drupal is not packaged with this file). If
auto-creation of either file fails, you will need to create the file
yourself. Use the template sites/default/default.settings.php or
sites/default/default.services.yml respectively.
Drupal will try to automatically create a settings.php configuration file,
which is normally in the directory sites/default (to avoid problems when
upgrading, Drupal is not packaged with this file). If auto-creation fails,
you will need to create this file yourself, using the file
sites/default/default.settings.php as a template.
For example, on a Unix/Linux command line, you can make a copy of the
default.settings.php and default.services.yml files with the commands:
default.settings.php file with the command:
cp sites/default/default.settings.php sites/default/settings.php
cp sites/default/default.services.yml sites/default/services.yml
Next, grant write privileges to the file to everyone (including the web
server) with the command:
chmod a+w sites/default/settings.php
chmod a+w sites/default/services.yml
Be sure to set the permissions back after the installation is finished!
Sample command:
chmod go-w sites/default/settings.php
chmod go-w sites/default/services.yml
c. Write permissions after install.
......@@ -184,7 +200,6 @@ INSTALLATION
from a Unix/Linux command line:
chmod go-w sites/default/settings.php
chmod go-w sites/default/services.yml
chmod go-w sites/default
4. Verify that the site is working.
......@@ -197,7 +212,7 @@ INSTALLATION
5. Change file system storage settings (optional).
The files directory created in step 4 is the default file system path used to
The files directory created in step 3 is the default file system path used to
store all uploaded files, as well as some temporary files created by
Drupal. After installation, you can modify the file system path to store
uploaded files in a different location.
......@@ -224,11 +239,19 @@ INSTALLATION
mkdir uploads
chmod a+w uploads
b. Navigate to Administration > Configuration > Media > File system, and
enter the desired path. Note that if you want to use private file storage,
you need to first enter the path for private files and save the
configuration, and then change the "Default download method" setting and
save again.
b. Open your settings.php in a plain-text editor, and uncomment (remove the #
at the start of line) this line:
# $settings['file_public_path'] = 'sites/default/files';
Enter the desired path and save the file.
If you want to use private file storage, you need to uncomment (remove
the # at the start of line) the following line in settings.php:
# $settings['file_private_path'] = '';
Enter the path for private files and save the file.
Changing the file system path after files have been uploaded may cause
unexpected problems on an existing site. If you modify the file system path
......
Drupal core is built and maintained by the Drupal project community. Everyone is
encouraged to submit issues and changes (patches) to improve Drupal, and to
contribute in other ways -- see http://drupal.org/contribute to find out how.
Branch maintainers
------------------
The Drupal Core branch maintainers oversee the development of Drupal as a
whole. The branch maintainers for Drupal 8 are:
- Dries Buytaert 'dries' http://drupal.org/user/1
- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
- Angela Byron 'webchick' http://drupal.org/user/24967
- Alex Pott 'alexpott' http://drupal.org/user/157725
Component maintainers
contribute in other ways -- see https://www.drupal.org/contribute to find out
how.
This file lists the active maintainers. For a list of past maintainers, see:
https://www.drupal.org/core/maintainers/past
Core committers
---------------
The Drupal Core committers oversee the development of Drupal as a whole. The
core committers for Drupal are (per major version, in alphabetical order):
Drupal 8
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
(Framework Manager)
- Dries Buytaert 'dries' https://www.drupal.org/u/dries
(BDFL, Product Manager)
- Angela Byron 'webchick' https://www.drupal.org/u/webchick
(Product Manager)
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
(Framework Manager, Release Manager)
- Jess Myrbo 'xjm' https://www.drupal.org/u/xjm
(Release Manager)
- Alex Pott 'alexpott' https://www.drupal.org/u/alexpott
(Framework Manager)
- Scott Reeves 'Cottser' https://www.drupal.org/u/cottser
(Framework Manager - Frontend)
Provisional membership:
- Chris McCafferty 'cilefen' https://www.drupal.org/u/cilefen
(Release Manager)
Drupal 7
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
(Framework Manager)
- David Rothstein 'David_Rothstein' https://www.drupal.org/u/david_rothstein
(Release Manager, Framework Manager, Product Manager)
- Stefan Ruijsenaars 'stefan.r' https://www.drupal.org/u/stefanr-0
(Release Manager, Product Manager)
Provisional membership: None at this time.
Subsystem maintainers
---------------------
The Drupal Core component maintainers oversee the development of Drupal
subsystems. See http://drupal.org/contribute/core-maintainers for more
information on their responsibilities, and to find out how to become a component
maintainer. Current component maintainers for Drupal 8:
The Drupal Core subsystem maintainers oversee the development of Drupal
subsystems. See https://www.drupal.org/contribute/core-maintainers for more
information on their responsibilities, and to find out how to become a subsystem
maintainer. Current subsystem maintainers for Drupal 8:
Ajax system
- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
- Earl Miles 'merlinofchaos' http://drupal.org/user/26979
Asset library system
Actions
- ?
Authentication and authorization system
Aggregator
- ?
Base system
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
Batch system
- Yves Chedemois 'yched' http://drupal.org/user/39567
Ajax
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
Bootstrap system
Asset Library API
- ?
Cache system
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
- Mark Sonnabaum 'msonnabaum' http://drupal.org/user/75278
Authentication and Authorization
- ?
Configuration system
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
- Alex Pott 'alexpott' http://drupal.org/user/157725
- Matthew Tift 'mtift' https://drupal.org/user/751908
Automated Cron
- ?
Configuration entity system
- Alex Pott 'alexpott' http://drupal.org/user/157725
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
- Tim Plunkett 'tim.plunkett' http://drupal.org/user/241634
Ban
- ?
Cron system
- Derek Wright 'dww' http://drupal.org/user/46549
Bartik
- Emma Maria Karayiannis 'emma.maria' https://www.drupal.org/u/emma.maria
CSS
- John Albin Wilkins 'JohnAlbin' http://drupal.org/user/32095
- Lewis Nyman 'LewisNyman' https://drupal.org/user/751964
Base system
- ?
Database system
- Larry Garfield 'Crell' http://drupal.org/user/26398
Basic Auth
- Klaus Purer 'klausi' https://www.drupal.org/u/klausi
- Juampy Novillo Requena 'juampy' https://www.drupal.org/u/juampy
MySQL DB driver
- Larry Garfield 'Crell' http://drupal.org/user/26398
- David Strauss 'David Strauss' http://drupal.org/user/93254
Batch API
- ?
PostgreSQL DB driver
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
- Josh Waihi 'fiasco' http://drupal.org/user/188162
BigPipe
- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
Sqlite DB driver
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
Block
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
- Ben Dougherty 'benjy' https://www.drupal.org/u/benjy
Database update system
- ?
Block Content
- Lee Rowlands 'larowlan' https://www.drupal.org/u/larowlan
Entity system
- Wolfgang Ziegler 'fago' http://drupal.org/user/16747
- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
- Franz Heinzmann 'Frando' http://drupal.org/user/21850
- Sascha Grossenbacher 'Berdir' http://drupal.org/user/214652
Book
- Peter Wolanin 'pwolanin' https://www.drupal.org/u/pwolanin
Extension system
Bootstrap
- ?
Field system
- Yves Chedemois 'yched' http://drupal.org/user/39567
- Kristof De Jaeger 'swentel' http://drupal.org/user/107403
- Andrei Mateescu 'amateescu' http://drupal.org/user/729614
Breakpoint
- Peter Droogmans 'attiks' https://www.drupal.org/u/attiks
- Marc Drummond 'mdrummond' https://www.drupal.org/u/mdrummond
File system
- Andrew Morton 'drewish' http://drupal.org/user/34869
- Aaron Winborn 'aaron' http://drupal.org/user/33420
Cache
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
Form system
- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
- Wolfgang Ziegler 'fago' http://drupal.org/user/16747
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
- Tim Plunkett 'tim.plunkett' http://drupal.org/user/241634
- Franz Heinzmann 'Frando' http://drupal.org/user/21850
CKEditor
- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
- Marek 'mlewand' Lewandowski https://www.drupal.org/u/mlewand
Image system
- Claudiu Cristea 'claudiu.cristea' https://drupal.org/user/56348
Classy
- David Hernandez 'davidhernandez' https://www.drupal.org/u/davidhernandez
- Morten Birch Heide-Jørgensen 'mortendk' https://www.drupal.org/u/mortendk
Install system
Color
- ?
JavaScript
- Théodore Biadala 'nod_' http://drupal.org/user/598310
Comment
- Lee Rowlands 'larowlan' https://www.drupal.org/u/larowlan
- Andrey Postnikov 'andypost' https://www.drupal.org/u/andypost
Language system
- Francesco Placella 'plach' http://drupal.org/user/183211
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
Configuration API
- Alex Pott 'alexpott' https://www.drupal.org/u/alexpott
- Matthew Tift 'mtift' https://www.drupal.org/u/mtift
Lock system
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
Configuration Entity API
- Alex Pott 'alexpott' https://www.drupal.org/u/alexpott
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
Mail system
- ?
Configuration UI
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
Markup
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
Configuration Translation
- Gábor Hojtsy 'Gábor Hojtsy' https://www.drupal.org/u/gábor-hojtsy
- Tobias Stöckler 'tstoeckler' https://www.drupal.org/u/tstoeckler
- Vijayachandran Mani 'vijaycs85' https://www.drupal.org/u/vijaycs85
Migrate
- Ben Dougherty 'benjy' https://drupal.org/user/1852732
- Michael Anello 'ultimike' https://drupal.org/user/51132
- Mike Ryan 'mikeryan' http://drupal.org/user/4420
Contact
- Lee Rowlands 'larowlan' https://www.drupal.org/u/larowlan
- Jibran Ijaz 'jibran' https://www.drupal.org/u/jibran
- Andrey Postnikov 'andypost' https://www.drupal.org/u/andypost
Menu system
Content Moderation
- Tim Millwood 'timmillwood' https://www.drupal.org/u/timmillwood
Path system
- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
Content Translation
- Francesco Placella 'plach' https://www.drupal.org/u/plach
Plugin system
- Kris Vanderwater 'EclipseGc' http://drupal.org/user/61203
- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
- Tim Plunkett 'tim.plunkett' http://drupal.org/user/241634
Contextual
- ?
Queue system
- James Gilliland 'neclimdul' http://drupal.org/user/48673
- Mark Sonnabaum 'msonnabaum' http://drupal.org/user/75278
Cron
- ?
Render system
- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
- Franz Heinzmann 'Frando' http://drupal.org/user/21850
CSS
- John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
Request processing system
- Larry Garfield 'Crell' http://drupal.org/user/26398
Database API
- Larry Garfield 'Crell' https://www.drupal.org/u/crell
Routing system
- Larry Garfield 'Crell' http://drupal.org/user/26398
- Tim Plunkett 'tim.plunkett' http://drupal.org/user/241634
MySQL DB driver
- Larry Garfield 'Crell' https://www.drupal.org/u/crell
- David Strauss 'David Strauss' https://www.drupal.org/u/david-strauss
Theme system
- Alex Bronstein 'effulgentsia' http://drupal.org/user/78040
- John Albin Wilkins 'JohnAlbin' http://drupal.org/user/32095
- Jen Lampton 'jenlampton' http://drupal.org/user/85586
- Scott Reeves 'Cottser' http://drupal.org/user/1167326
- Fabian Franz 'Fabianx' http://drupal.org/user/693738
- Joël Pittet 'joelpittet' https://drupal.org/user/160302
PostgreSQL DB driver
- ?
Token system
- Dave Reid 'davereid' http://drupal.org/user/53892
Sqlite DB driver
- ?
Transliteration system
- Andrei Mateescu 'amateescu' http://drupal.org/user/729614
- Damien Tournoud 'DamZ' http://drupal.org/user/22211
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
- Jennifer Hodgdon 'jhodgdon' http://drupal.org/user/155601
Database Logging
- ?
Database Update API
- ?
Topic coordinators
------------------
DateTime
- Jonathan Hedstrom 'jhedstrom' https://www.drupal.org/u/jhedstrom
- Matthew Donadio 'mpdonadio' https://www.drupal.org/u/mpdonadio
Accessibility
- Mike Gifford 'mgifford' http://drupal.org/user/27930
- Jesse Renée Beach 'jessebeach' http://drupal.org/user/748566
DateTime Range
- Jonathan Hedstrom 'jhedstrom' https://www.drupal.org/u/jhedstrom
- Matthew Donadio 'mpdonadio' https://www.drupal.org/u/mpdonadio
Documentation
- Jennifer Hodgdon 'jhodgdon' http://drupal.org/user/155601
Dynamic Page Cache
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
Translations
- ?
Editor
- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
User experience and usability
- Roy Scholten 'yoroy' http://drupal.org/user/41502
- Bojhan Somers 'Bojhan' http://drupal.org/user/87969
Entity API
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
- Sascha Grossenbacher 'Berdir' https://www.drupal.org/u/berdir
- Francesco Placella 'plach' https://www.drupal.org/u/plach
- Tobias Stöckler 'tstoeckler' https://www.drupal.org/u/tstoeckler
Node Access
- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
- Ken Rickard 'agentrickard' http://drupal.org/user/20975
- Jess Myrbo 'xjm' http://drupal.org/user/65776
Extension API
- ?
Field API
- Andrei Mateescu 'amateescu' https://www.drupal.org/u/amateescu
Security team
-----------------
Field UI
- Yves Chedemois 'yched' https://www.drupal.org/u/yched
- Andrei Mateescu 'amateescu' https://www.drupal.org/u/amateescu
To report a security issue, see: https://drupal.org/security-team/report-issue
File
- ?
The Drupal security team provides Security Advisories for vulnerabilities,
assists developers in resolving security issues, and provides security
documentation. See http://drupal.org/security-team for more information. The
security team lead is:
Filter
- ?
- Michael Hess 'mlhess' https://drupal.org/user/102818
Forum
- Lee Rowlands 'larowlan' https://www.drupal.org/u/larowlan
Form API
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
Module maintainers
------------------
History
- Andrey Postnikov 'andypost' https://www.drupal.org/u/andypost
Action module
Hypertext Application Language (HAL)
- ?
Aggregator module
- Paris Liakos 'ParisLiakos' http://drupal.org/user/1011436
Ban module
Help
- ?
Basic Auth module
- Klaus Purer 'klausi' http://drupal.org/user/262198
- Juampy Novillo Requena 'juampy' https://drupal.org/user/682736
Image
- Claudiu Cristea 'claudiu.cristea' https://www.drupal.org/u/claudiu.cristea
Block module
- Tim Plunkett 'tim.plunkett' http://drupal.org/user/241634
- Ben Dougherty 'benjy' http://drupal.org/user/1852732
Installer
- ?
Block Content module
- Lee Rowlands 'larowlan' http://drupal.org/user/395439
Interface Translation (locale)
- Gábor Hojtsy 'Gábor Hojtsy' https://www.drupal.org/u/gábor-hojtsy
Book module
- Peter Wolanin 'pwolanin' http://drupal.org/user/49851
JavaScript
- Théodore Biadala 'nod_' https://www.drupal.org/u/nod_
- Kay Leung 'droplet' https://www.drupal.org/u/droplet
Breakpoint module
- Peter Droogmans 'attiks' http://drupal.org/user/105002
- Marc Drummond 'mdrummond' http://www.drupal.org/user/360968/
Language
- Francesco Placella 'plach' https://www.drupal.org/u/plach
- Daniel F. Kudwien 'sun' https://www.drupal.org/u/sun
CKEditor module
- Wim Leers 'Wim Leers' http://drupal.org/user/99777
Link Field
- Weber Macedo 'Mac_Weber' https://www.drupal.org/u/mac_weber
Color module
Lock
- ?
Comment module
- Dick Olsson 'dixon_' http://drupal.org/user/239911
- Lee Rowlands 'larowlan' http://drupal.org/user/395439
- Andrey Postnikov 'andypost' https://drupal.org/user/118908
Configuration module
- Tim Plunkett 'tim.plunkett' http://drupal.org/user/241634
Configuration Translation module
- Gábor Hojtsy 'Gábor Hojtsy' http://drupal.org/user/4166
- Tobias Stöckler 'tstoeckler' https://drupal.org/user/107158
- Vijayachandran Mani 'vijaycs85' https://drupal.org/user/93488
Mail
- ?
Contact module
- Lee Rowlands 'larowlan' http://drupal.org/user/395439
- Tim Eisenhuth 'tim-e' https://www.drupal.org/user/1439114
Markup
- ?
Content Translation module
- Francesco Placella 'plach' http://drupal.org/user/183211
Migrate
- Adam Globus-Hoenich 'phenaproxima' https://www.drupal.org/u/phenaproxima
- Ben Dougherty 'benjy' https://www.drupal.org/u/benjy
- Lucas Hedding 'heddn' https://www.drupal.org/u/heddn
- Michael Anello 'ultimike' https://www.drupal.org/u/ultimike
- Mike Ryan 'mikeryan' https://www.drupal.org/u/mikeryan
- Vicki Spagnolo 'quietone' https://www.drupal.org/u/quietone
Migrate (Drupal)
- Ben Dougherty 'benjy' https://www.drupal.org/u/benjy
- Lucas Hedding 'heddn' https://www.drupal.org/u/heddn
- Michael Anello 'ultimike' https://www.drupal.org/u/ultimike
- Mike Ryan 'mikeryan' https://www.drupal.org/u/mikeryan
- Vicki Spagnolo 'quietone' https://www.drupal.org/u/quietone
Menu
- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
- Peter Wolanin 'pwolanin' https://www.drupal.org/u/pwolanin
Menu Link Content
- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
- Peter Wolanin 'pwolanin' https://www.drupal.org/u/pwolanin
Menu UI
- ?
Contextual module
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
Node
- ?
Database Logging module
- Khalid Baheyeldin 'kbahey' http://drupal.org/user/4063
Node Access
- Ken Rickard 'agentrickard' https://www.drupal.org/u/agentrickard
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
- Jess Myrbo 'xjm' https://www.drupal.org/u/xjm
DateTime module
Options
- ?
Email module
- Nils Destoop 'zuuperman' https://drupal.org/user/361625
Outside In
- Ted Bowman 'tedbow' https://www.drupal.org/u/tedbow
Editor module
- Wim Leers 'Wim Leers' http://drupal.org/user/99777
Page Cache
- Lorenz Schori 'znerol' https://www.drupal.org/u/znerol
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
Entity Reference module
- Amitai Burstein 'Amitaibu' http://drupal.org/user/57511
- Andrei Mateescu 'amateescu' http://drupal.org/user/729614
Path
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
Field UI module
- Yves Chedemois 'yched' http://drupal.org/user/39567
- Kristof De Jaeger 'swentel' http://drupal.org/user/107403
- Andrei Mateescu 'amateescu' http://drupal.org/user/729614
Plugin
- Kris Vanderwater 'EclipseGc' https://www.drupal.org/u/eclipseGc
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
File module
- Aaron Winborn 'aaron' http://drupal.org/user/33420
Queue
- James Gilliland 'neclimdul' https://www.drupal.org/u/neclimdul
Filter module
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
Quick Edit
- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
- Théodore Biadala 'nod_' https://www.drupal.org/u/nod_
Forum module
- Lee Rowlands 'larowlan' http://drupal.org/user/395439
RDF
- Stéphane Corlosquet 'scor' https://www.drupal.org/u/scor
History module
- Andrey Postnikov 'andypost' http://drupal.org/user/118908
Render API
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
Hypertext Application Language (HAL) module
- ?
Request Processing
- Larry Garfield 'Crell' https://www.drupal.org/u/crell
Help module
- ?
REST
- Klaus Purer 'klausi' https://www.drupal.org/u/klausi
- Larry Garfield 'Crell' https://www.drupal.org/u/crell
- Wim Leers 'Wim Leers' https://www.drupal.org/u/wim-leers
Image module
- Claudiu Cristea 'claudiu.cristea' https://drupal.org/user/56348
Responsive Image
- Peter Droogmans 'attiks' https://www.drupal.org/u/attiks
- Marc Drummond 'mdrummond' https://www.drupal.org/u/mdrummond
- Jelle Sebreghts 'Jelle_S' https://www.drupal.org/u/jelle_s
Interface Translation (locale) module
- Gábor Hojtsy 'Gábor Hojtsy' http://drupal.org/user/4166
Routing
- Larry Garfield 'Crell' https://www.drupal.org/u/crell
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
Language module
- Francesco Placella 'plach' http://drupal.org/user/183211
- Gábor Hojtsy 'Gábor Hojtsy' http://drupal.org/user/4166
Search
- Peter Wolanin 'pwolanin' https://www.drupal.org/u/pwolanin
Link module
- ?
Serialization
- Damian Lee 'damiankloip' https://www.drupal.org/u/damiankloip
Menu UI module
Seven
- ?
Menu Link module
- Peter Wolanin 'pwolanin' http://drupal.org/user/49851
Shortcut
- Tobias Stöckler 'tstoeckler' https://www.drupal.org/u/tstoeckler
- Jibran Ijaz 'jibran' https://www.drupal.org/u/jibran
Migrate module
- Ben Dougherty 'benjy' https://drupal.org/user/1852732
- Michael Anello 'ultimike' https://drupal.org/user/51132
- Mike Ryan 'mikeryan' http://drupal.org/user/4420
Stable
- Scott Reeves 'Cottser' https://www.drupal.org/u/cottser
Migrate (Drupal) module
- Ben Dougherty 'benjy' https://drupal.org/user/1852732
- Michael Anello 'ultimike' https://drupal.org/user/51132
- Mike Ryan 'mikeryan' http://drupal.org/user/4420
Stark
- John Albin Wilkins 'JohnAlbin' https://www.drupal.org/u/johnalbin
Node module
- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
- David Strauss 'David Strauss' http://drupal.org/user/93254
Statistics
- Tim Millwood 'timmillwood' https://www.drupal.org/u/timmillwood
Number module
- Kristof De Jaeger 'swentel' http://drupal.org/user/107403
Syslog
- Khalid Baheyeldin 'kbahey' https://www.drupal.org/u/kbahey
Options module
- Yves Chedemois 'yched' http://drupal.org/user/39567
Path module
System (module)
- ?
Phone module
- Dave Reid 'davereid' http://drupal.org/user/53892
Taxonomy
- Jess Myrbo 'xjm' https://www.drupal.org/u/xjm
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
Quick Edit module
- Wim Leers 'Wim Leers' http://drupal.org/user/99777
- Théodore Biadala 'nod_' http://drupal.org/user/598310
Telephone
- ?
RDF module
- Stéphane Corlosquet 'scor' http://drupal.org/user/52142
Testing framework
- Alex Pott 'alexpott' https://www.drupal.org/u/alexpott
- Sascha Grossenbacher 'Berdir' https://www.drupal.org/u/berdir
- Klaus Purer 'klausi' https://www.drupal.org/u/klausi
- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
REST module
- Klaus Purer 'klausi' http://drupal.org/user/262198
- Larry Garfield 'Crell' http://drupal.org/user/26398
Text Field
- ?
Responsive Image module
- Peter Droogmans 'attiks' http://drupal.org/user/105002
- Marc Drummond 'mdrummond' http://www.drupal.org/user/360968/
Theme API
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
- Joël Pittet 'joelpittet' https://www.drupal.org/u/joelpittet
- Lauri Eskola 'lauriii' https://www.drupal.org/u/lauriii
Search module
- Jennifer Hodgdon 'jhodgdon' https://drupal.org/user/155601
- Peter Wolanin 'pwolanin' https://drupal.org/user/49851
Token
- ?
Serialization module
- Damian Lee 'damiankloip' http://drupal.org/user/1037976
Toolbar
- Théodore Biadala 'nod_' https://www.drupal.org/u/nod_
Shortcut module
- Tobias Stöckler 'tstoeckler' https://www.drupal.org/user/107158
- Jibran Ijaz 'jibran' https://www.drupal.org/user/1198144
Tour
- Nick Schuch 'nick_schuch' https://www.drupal.org/u/nick_schuch
Simpletest module
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
- Sascha Grossenbacher 'Berdir' http://drupal.org/user/214652
- Alex Pott 'alexpott' http://drupal.org/user/157725
Tracker
- ?
Statistics module
- Tim Millwood 'timmillwood' http://drupal.org/user/227849
Transliteration
- Andrei Mateescu 'amateescu' https://www.drupal.org/u/amateescu
Syslog module
- Khalid Baheyeldin 'kbahey' http://drupal.org/user/4063
Typed Data
- Wolfgang Ziegler 'fago' https://www.drupal.org/u/fago
System module
Update UI
- ?
Taxonomy module
- Jess Myrbo 'xjm' http://drupal.org/user/65776
- Nathaniel Catchpole 'catch' http://drupal.org/user/35733
- Benjamin Doherty 'bangpound' http://drupal.org/user/100456
Text module
- ?
User
- Moshe Weitzman 'moshe weitzman' https://www.drupal.org/u/moshe-weitzman
Toolbar module
- Théodore Biadala 'nod_' http://drupal.org/user/598310
Views
- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
- Damian Lee 'damiankloip' https://www.drupal.org/u/damiankloip
- Jess Myrbo 'xjm' https://www.drupal.org/u/xjm
- Len Swaneveld 'Lendude' https://www.drupal.org/u/lendude
Tour module
- Nick Schuch 'nick_schuch' http://drupal.org/user/1412036
Topic maintainers
-----------------
Tracker module
- David Strauss 'David Strauss' http://drupal.org/user/93254
Accessibility
- Mike Gifford 'mgifford' https://www.drupal.org/u/mgifford
- Andrew Macpherson 'andrewmacpherson' https://www.drupal.org/u/andrewmacpherson
Update module
- Derek Wright 'dww' http://drupal.org/user/46549
Documentation
- ?
User module
- Moshe Weitzman 'moshe weitzman' http://drupal.org/user/23
- David Strauss 'David Strauss' http://drupal.org/user/93254
Performance
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
Views module
- Daniel Wehner 'dawehner' http://drupal.org/user/99340
- Tim Plunkett 'tim.plunkett' http://drupal.org/user/241634
- Damian Lee 'damiankloip' http://drupal.org/user/1037976
- Jess Myrbo 'xjm' http://drupal.org/user/65776
Testing
- ?
Views UI module
- Daniel Wehner 'dawehner' http://drupal.org/user/99340
- Tim Plunkett 'tim.plunkett' http://drupal.org/user/241634
- Damian Lee 'damiankloip' http://drupal.org/user/1037976
Usability
- Roy Scholten 'yoroy' https://www.drupal.org/u/yoroy
- Bojhan Somers 'Bojhan' https://www.drupal.org/u/bojhan
Provisional membership: None at this time.
Theme maintainers
Security team
-----------------
Bartik theme
- Jen Simmons 'jensimmons' http://drupal.org/user/140882
- Emma Maria Karayiannis 'emma.maria' https://drupal.org/user/2104556
Seven theme
- Lewis Nyman 'LewisNyman' https://drupal.org/user/751964
To report a security issue, see:
https://www.drupal.org/security-team/report-issue
Stark theme
- John Albin Wilkins 'JohnAlbin' http://drupal.org/user/32095
The Drupal security team provides Security Advisories for vulnerabilities,
assists developers in resolving security issues, and provides security
documentation. See https://www.drupal.org/security-team for more information.
The security team lead is:
- Michael Hess 'mlhess' https://www.drupal.org/u/mlhess
Initiative owners
-----------------
Initiative coordinators
-----------------------
The Drupal Core Initiatives owners oversee approved projects that re-architect
or otherwise improve large areas of Drupal core. See
http://drupal.org/community-initiatives/drupal-core for more information on
their responsibilities. The initiative owners for Drupal 8 are:
The Drupal Core Initiative coordinators oversee approved projects that
re-architect or otherwise improve large areas of Drupal core. See
https://www.drupal.org/community-initiatives/drupal-core for more information on
their responsibilities. The initiative coordinators for Drupal 8 are:
Configuration management
- Greg Dunlap 'heyrocker' http://drupal.org/user/128537
Multi-lingual
- Gábor Hojtsy 'Gábor Hojtsy' https://www.drupal.org/u/gábor-hojtsy
Design
- Jeff Burns 'Jeff Burnz' http://drupal.org/user/61393
Workflow Initiative
- Dick Olsson 'dixon_' https://www.drupal.org/u/dixon_
Mobile
- John Albin Wilkins 'JohnAlbin' http://drupal.org/user/32095
PHPUnit Initiative
- Klaus Purer 'klausi' https://www.drupal.org/u/klausi
- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
Multi-lingual
- Gábor Hojtsy 'Gábor Hojtsy' http://drupal.org/user/4166
Provisional membership: None at this time.
Web services
- Larry Garfield 'Crell' http://drupal.org/user/26398
Core mentoring leads
Core mentoring coordinators
---------------------
The Drupal Core mentoring leads inspire, enable, and encourage new core
contributors. They also work on the core tools, process, and community to make
it easier for new contributors to get involved. The mentoring leads are:
The Drupal Core mentors inspire, enable, and encourage new core contributors.
See https://www.drupal.org/core-mentoring for more information about mentoring.
Mentoring coordinators recruit and coach other mentors. They work on contributor
tools, documentation, and processes to make it easier for new contributors to
get involved. They organize communications and logistics, and actively
participate in mentoring.
- Lucas Hedding 'heddn' https://www.drupal.org/u/heddn
- Valery Lourie 'valthebald' https://www.drupal.org/u/valthebald
- Alina Mackenzie 'alimac' https://www.drupal.org/u/alimac
- Jess Myrbo 'xjm' https://www.drupal.org/u/xjm
- Andrea Soper 'ZenDoodles' https://www.drupal.org/u/zendoodles
- Cathy Theys 'YesCT' https://www.drupal.org/u/yesct
- Jess Myrbo 'xjm' http://drupal.org/user/65776
- Cathy Theys 'YesCT' https://drupal.org/user/258568
- Scott Reeves 'Cottser' http://drupal.org/user/1167326
- Andrea Soper 'ZenDoodles' https://drupal.org/user/226976
Provisional membership: None at this time.
INTRODUCTION
------------
This document describes how to update your Drupal site between 8.x.x minor and
patch versions; for example, from 8.1.2 to 8.1.3, or from 8.3.5 to 8.4.0.
To upgrade from a previous major version (for example, Drupal 6 or 7), the
process involves importing site configuration and content from your old site
into a new Drupal 8 site. The tools and process are currently experimental,
rather than being fully supported, so be sure to test in a development
environment. You will need to use the core Migrate Drupal UI module which
provides a user interface for the Migrate and Migrate Drupal modules included
in core. See https://www.drupal.org/upgrade/migrate for details, and
https://www.drupal.org/node/2167633 for known issues.
First steps and definitions:
* If you are upgrading to Drupal version x.y.z, then x is known as the major
version number, y is known as the minor version number, and z is known as
the patch version number. The download file will be named
drupal-x.y.z.tar.gz (or drupal-x.y.z.zip). Previous Drupal versions used
only x.y (MAJOR.MINOR) to designate their versions.
* All directories mentioned in this document are relative to the directory of
your Drupal installation.
* Make a full backup of all files, directories, and your database(s) before
starting, and save it outside your Drupal installation directory.
Instructions may be found at
https://www.drupal.org/upgrade/backing-up-the-db
* It is wise to try an update or upgrade on a test copy of your site before
applying it to your live site. Even minor updates can cause your site's
behavior to change.
* Each new release of Drupal has release notes, which explain the changes made
since the previous version and any special instructions needed to update or
upgrade to the new version. You can find a link to the release notes for the
version you are upgrading or updating to on the Drupal project page
(https://www.drupal.org/project/drupal).
UPDATE PROBLEMS
----------------
If you encounter errors during this process,
* Note any error messages you see.
* Restore your site to its previous state, using the file and database backups
you created before you started the update process. Do not attempt to do
further updates on a site that had update problems.
* Consult one of the support options listed on https://www.drupal.org/support
More in-depth information on updating and upgrading can be found at
https://www.drupal.org/upgrade
MINOR AND PATCH VERSION UPDATES
-------------------------------
To update from one 8.x.x version of Drupal to any later 8.x.x version, after
following the instructions in the INTRODUCTION section at the top of this file:
1. Log in as a user with the permission "Administer software updates".
2. Go to Administration > Configuration > Development > Maintenance mode.
Enable the "Put site into maintenance mode" checkbox and save the
configuration.
3. Remove the 'core' and 'vendor' directories. Also remove all of the files
in the top-level directory, except any that you added manually.
If you made modifications to files like .htaccess, composer.json, or
robots.txt you will need to re-apply them from your backup, after the new
files are in place.
Sometimes an update includes changes to default.settings.php (this will be
noted in the release notes). If that's the case, follow these steps:
- Locate your settings.php file in the /sites/* directory. (Typically
sites/default.)
- Make a backup copy of your settings.php file, with a different file name.
- Make a copy of the new default.settings.php file, and name the copy
settings.php (overwriting your previous settings.php file).
- Copy the custom and site-specific entries from the backup you made into the
new settings.php file. You will definitely need the lines giving the
database information, and you will also want to copy in any other
customizations you have added.
You can find the release notes for your version at
https://www.drupal.org/project/drupal. At bottom of the project page under
"Downloads" use the link for your version of Drupal to view the release
notes. If your version is not listed, use the 'View all releases' link. From
this page you can scroll down or use the filter to find your version and its
release notes.
4. Download the latest Drupal 8.x.x release from https://www.drupal.org to a
directory outside of your web root. Extract the archive and copy the files
into your Drupal directory.
On a typical Unix/Linux command line, use the following commands to download
and extract:
wget https://www.drupal.org/files/projects/drupal-x.y.z.tar.gz
tar -zxvf drupal-x.y.z.tar.gz
This creates a new directory drupal-x.y.z/ containing all Drupal files and
directories. Copy the files into your Drupal installation directory:
cp -R drupal-x.y.z/* drupal-x.y.z/.htaccess /path/to/your/installation
If you do not have command line access to your server, download the archive
from https://www.drupal.org using your web browser, extract it, and then use
an FTP client to upload the files to your web root.
5. Re-apply any modifications to files such as .htaccess, composer.json, or
robots.txt.
6. Run update.php by visiting http://www.example.com/update.php (replace
www.example.com with your domain name). This will update the core database
tables.
If you are unable to access update.php do the following:
- Open settings.php with a text editor.
- Find the line that says:
$settings['update_free_access'] = FALSE;
- Change it into:
$settings['update_free_access'] = TRUE;
- Once the update is done, $settings['update_free_access'] must be reverted
to FALSE.
7. Go to Administration > Reports > Status report. Verify that everything is
working as expected.
8. Ensure that $settings['update_free_access'] is FALSE in settings.php.
9. Go to Administration > Configuration > Development > Maintenance mode.
Disable the "Put site into maintenance mode" checkbox and save the
configuration.
INTRODUCTION
------------
This document describes how to:
* Update your Drupal site from one minor 8.x version to another minor 8.x
version; for example, from 8.8 to 8.9, or from 8.6 to 8.10.
* Migrate your Drupal site to version 8.x.
First steps and definitions:
* If you are upgrading to Drupal version x.y, then x is known as the major
version number, and y is known as the minor version number. The download
file will be named drupal-x.y.tar.gz (or drupal-x.y.zip).
* All directories mentioned in this document are relative to the directory of
your Drupal installation.
* Make a full backup of all files, directories, and your database(s) before
starting, and save it outside your Drupal installation directory.
Instructions may be found at http://drupal.org/upgrade/backing-up-the-db
* It is wise to try an update or upgrade on a test copy of your site before
applying it to your live site. Even minor updates can cause your site's
behavior to change.
* Each new release of Drupal has release notes, which explain the changes made
since the previous version and any special instructions needed to update or
upgrade to the new version. You can find a link to the release notes for the
version you are upgrading or updating to on the Drupal project page
(http://drupal.org/project/drupal).
UPGRADE PROBLEMS
----------------
If you encounter errors during this process,
* Note any error messages you see.
* Restore your site to its previous state, using the file and database backups
you created before you started the upgrade process. Do not attempt to do
further upgrades on a site that had update problems.
* Consult one of the support options listed on http://drupal.org/support
More in-depth information on upgrading can be found at http://drupal.org/upgrade
MINOR VERSION UPDATES
---------------------
To update from one minor 8.x version of Drupal to any later 8.x version, after
following the instructions in the INTRODUCTION section at the top of this file:
1. Log in as a user with the permission "Administer software updates".
2. Go to Administration > Configuration > Development > Maintenance mode.
Enable the "Put site into maintenance mode" checkbox and save the
configuration.
3. Remove all old core files and directories, except for the 'sites' directory
and any custom files you added elsewhere.
If you made modifications to files like .htaccess, composer.json, or
robots.txt you will need to re-apply them from your backup, after the new
files are in place.
Sometimes an update includes changes to default.settings.php (this will be
noted in the release notes). If that's the case, follow these steps:
- Make a backup copy of your settings.php file, with a different file name.
- Make a copy of the new default.settings.php file, and name the copy
settings.php (overwriting your previous settings.php file).
- Copy the custom and site-specific entries from the backup you made into the
new settings.php file. You will definitely need the lines giving the
database information, and you will also want to copy in any other
customizations you have added.
4. Download the latest Drupal 8.x release from http://drupal.org to a
directory outside of your web root. Extract the archive and copy the files
into your Drupal directory.
On a typical Unix/Linux command line, use the following commands to download
and extract:
wget http://drupal.org/files/projects/drupal-x.y.tar.gz
tar -zxvf drupal-x.y.tar.gz
This creates a new directory drupal-x.y/ containing all Drupal files and
directories. Copy the files into your Drupal installation directory:
cp -R drupal-x.y/* drupal-x.y/.htaccess /path/to/your/installation
If you do not have command line access to your server, download the archive
from http://drupal.org using your web browser, extract it, and then use an
FTP client to upload the files to your web root.
5. Re-apply any modifications to files such as .htaccess, composer.json, or
robots.txt.
6. Run update.php by visiting http://www.example.com/update.php (replace
www.example.com with your domain name). This will update the core database
tables.
If you are unable to access update.php do the following:
- Open settings.php with a text editor.
- Find the line that says:
$settings['update_free_access'] = FALSE;
- Change it into:
$settings['update_free_access'] = TRUE;
- Once the upgrade is done, $settings['update_free_access'] must be
reverted to FALSE.
7. Go to Administration > Reports > Status report. Verify that everything is
working as expected.
8. Ensure that $settings['update_free_access'] is FALSE in settings.php.
9. Go to Administration > Configuration > Development > Maintenance mode.
Disable the "Put site into maintenance mode" checkbox and save the
configuration.
MAJOR VERSION MIGRATION
-----------------------
Upgrading from a prior major version of Drupal to Drupal 8.x is not possible.
The process now requires a migration to a Drupal 8.x site, using the Migrate
module in Drupal core.
Note that migration support in Drupal 8 is currently only partially implemented.
(function(t,e){if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,s){t.Backbone=e(t,s,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore");e(t,exports,i)}else{t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}})(this,function(t,e,i,r){var s=t.Backbone;var n=[];var a=n.push;var o=n.slice;var h=n.splice;e.VERSION="1.1.2";e.$=r;e.noConflict=function(){t.Backbone=s;return this};e.emulateHTTP=false;e.emulateJSON=false;var u=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,r){if(!c(this,"once",t,[e,r])||!e)return this;var s=this;var n=i.once(function(){s.off(t,n);e.apply(this,arguments)});n._callback=e;return this.on(t,n,r)},off:function(t,e,r){var s,n,a,o,h,u,l,f;if(!this._events||!c(this,"off",t,[e,r]))return this;if(!t&&!e&&!r){this._events=void 0;return this}o=t?[t]:i.keys(this._events);for(h=0,u=o.length;h<u;h++){t=o[h];if(a=this._events[t]){this._events[t]=s=[];if(e||r){for(l=0,f=a.length;l<f;l++){n=a[l];if(e&&e!==n.callback&&e!==n.callback._callback||r&&r!==n.context){s.push(n)}}}if(!s.length)delete this._events[t]}}return this},trigger:function(t){if(!this._events)return this;var e=o.call(arguments,1);if(!c(this,"trigger",t,e))return this;var i=this._events[t];var r=this._events.all;if(i)f(i,e);if(r)f(r,arguments);return this},stopListening:function(t,e,r){var s=this._listeningTo;if(!s)return this;var n=!e&&!r;if(!r&&typeof e==="object")r=this;if(t)(s={})[t._listenId]=t;for(var a in s){t=s[a];t.off(e,r,this);if(n||i.isEmpty(t._events))delete this._listeningTo[a]}return this}};var l=/\s+/;var c=function(t,e,i,r){if(!i)return true;if(typeof i==="object"){for(var s in i){t[e].apply(t,[s,i[s]].concat(r))}return false}if(l.test(i)){var n=i.split(l);for(var a=0,o=n.length;a<o;a++){t[e].apply(t,[n[a]].concat(r))}return false}return true};var f=function(t,e){var i,r=-1,s=t.length,n=e[0],a=e[1],o=e[2];switch(e.length){case 0:while(++r<s)(i=t[r]).callback.call(i.ctx);return;case 1:while(++r<s)(i=t[r]).callback.call(i.ctx,n);return;case 2:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a);return;case 3:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a,o);return;default:while(++r<s)(i=t[r]).callback.apply(i.ctx,e);return}};var d={listenTo:"on",listenToOnce:"once"};i.each(d,function(t,e){u[e]=function(e,r,s){var n=this._listeningTo||(this._listeningTo={});var a=e._listenId||(e._listenId=i.uniqueId("l"));n[a]=e;if(!s&&typeof r==="object")s=this;e[t](r,s,this);return this}});u.bind=u.on;u.unbind=u.off;i.extend(e,u);var p=e.Model=function(t,e){var r=t||{};e||(e={});this.cid=i.uniqueId("c");this.attributes={};if(e.collection)this.collection=e.collection;if(e.parse)r=this.parse(r,e)||{};r=i.defaults({},r,i.result(this,"defaults"));this.set(r,e);this.changed={};this.initialize.apply(this,arguments)};i.extend(p.prototype,u,{changed:null,validationError:null,idAttribute:"id",initialize:function(){},toJSON:function(t){return i.clone(this.attributes)},sync:function(){return e.sync.apply(this,arguments)},get:function(t){return this.attributes[t]},escape:function(t){return i.escape(this.get(t))},has:function(t){return this.get(t)!=null},set:function(t,e,r){var s,n,a,o,h,u,l,c;if(t==null)return this;if(typeof t==="object"){n=t;r=e}else{(n={})[t]=e}r||(r={});if(!this._validate(n,r))return false;a=r.unset;h=r.silent;o=[];u=this._changing;this._changing=true;if(!u){this._previousAttributes=i.clone(this.attributes);this.changed={}}c=this.attributes,l=this._previousAttributes;if(this.idAttribute in n)this.id=n[this.idAttribute];for(s in n){e=n[s];if(!i.isEqual(c[s],e))o.push(s);if(!i.isEqual(l[s],e)){this.changed[s]=e}else{delete this.changed[s]}a?delete c[s]:c[s]=e}if(!h){if(o.length)this._pending=r;for(var f=0,d=o.length;f<d;f++){this.trigger("change:"+o[f],this,c[o[f]],r)}}if(u)return this;if(!h){while(this._pending){r=this._pending;this._pending=false;this.trigger("change",this,r)}}this._pending=false;this._changing=false;return this},unset:function(t,e){return this.set(t,void 0,i.extend({},e,{unset:true}))},clear:function(t){var e={};for(var r in this.attributes)e[r]=void 0;return this.set(e,i.extend({},t,{unset:true}))},hasChanged:function(t){if(t==null)return!i.isEmpty(this.changed);return i.has(this.changed,t)},changedAttributes:function(t){if(!t)return this.hasChanged()?i.clone(this.changed):false;var e,r=false;var s=this._changing?this._previousAttributes:this.attributes;for(var n in t){if(i.isEqual(s[n],e=t[n]))continue;(r||(r={}))[n]=e}return r},previous:function(t){if(t==null||!this._previousAttributes)return null;return this._previousAttributes[t]},previousAttributes:function(){return i.clone(this._previousAttributes)},fetch:function(t){t=t?i.clone(t):{};if(t.parse===void 0)t.parse=true;var e=this;var r=t.success;t.success=function(i){if(!e.set(e.parse(i,t),t))return false;if(r)r(e,i,t);e.trigger("sync",e,i,t)};q(this,t);return this.sync("read",this,t)},save:function(t,e,r){var s,n,a,o=this.attributes;if(t==null||typeof t==="object"){s=t;r=e}else{(s={})[t]=e}r=i.extend({validate:true},r);if(s&&!r.wait){if(!this.set(s,r))return false}else{if(!this._validate(s,r))return false}if(s&&r.wait){this.attributes=i.extend({},o,s)}if(r.parse===void 0)r.parse=true;var h=this;var u=r.success;r.success=function(t){h.attributes=o;var e=h.parse(t,r);if(r.wait)e=i.extend(s||{},e);if(i.isObject(e)&&!h.set(e,r)){return false}if(u)u(h,t,r);h.trigger("sync",h,t,r)};q(this,r);n=this.isNew()?"create":r.patch?"patch":"update";if(n==="patch")r.attrs=s;a=this.sync(n,this,r);if(s&&r.wait)this.attributes=o;return a},destroy:function(t){t=t?i.clone(t):{};var e=this;var r=t.success;var s=function(){e.trigger("destroy",e,e.collection,t)};t.success=function(i){if(t.wait||e.isNew())s();if(r)r(e,i,t);if(!e.isNew())e.trigger("sync",e,i,t)};if(this.isNew()){t.success();return false}q(this,t);var n=this.sync("delete",this,t);if(!t.wait)s();return n},url:function(){var t=i.result(this,"urlRoot")||i.result(this.collection,"url")||M();if(this.isNew())return t;return t.replace(/([^\/])$/,"$1/")+encodeURIComponent(this.id)},parse:function(t,e){return t},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.has(this.idAttribute)},isValid:function(t){return this._validate({},i.extend(t||{},{validate:true}))},_validate:function(t,e){if(!e.validate||!this.validate)return true;t=i.extend({},this.attributes,t);var r=this.validationError=this.validate(t,e)||null;if(!r)return true;this.trigger("invalid",this,r,i.extend(e,{validationError:r}));return false}});var v=["keys","values","pairs","invert","pick","omit"];i.each(v,function(t){p.prototype[t]=function(){var e=o.call(arguments);e.unshift(this.attributes);return i[t].apply(i,e)}});var g=e.Collection=function(t,e){e||(e={});if(e.model)this.model=e.model;if(e.comparator!==void 0)this.comparator=e.comparator;this._reset();this.initialize.apply(this,arguments);if(t)this.reset(t,i.extend({silent:true},e))};var m={add:true,remove:true,merge:true};var y={add:true,remove:false};i.extend(g.prototype,u,{model:p,initialize:function(){},toJSON:function(t){return this.map(function(e){return e.toJSON(t)})},sync:function(){return e.sync.apply(this,arguments)},add:function(t,e){return this.set(t,i.extend({merge:false},e,y))},remove:function(t,e){var r=!i.isArray(t);t=r?[t]:i.clone(t);e||(e={});var s,n,a,o;for(s=0,n=t.length;s<n;s++){o=t[s]=this.get(t[s]);if(!o)continue;delete this._byId[o.id];delete this._byId[o.cid];a=this.indexOf(o);this.models.splice(a,1);this.length--;if(!e.silent){e.index=a;o.trigger("remove",o,this,e)}this._removeReference(o,e)}return r?t[0]:t},set:function(t,e){e=i.defaults({},e,m);if(e.parse)t=this.parse(t,e);var r=!i.isArray(t);t=r?t?[t]:[]:i.clone(t);var s,n,a,o,h,u,l;var c=e.at;var f=this.model;var d=this.comparator&&c==null&&e.sort!==false;var v=i.isString(this.comparator)?this.comparator:null;var g=[],y=[],_={};var b=e.add,w=e.merge,x=e.remove;var E=!d&&b&&x?[]:false;for(s=0,n=t.length;s<n;s++){h=t[s]||{};if(h instanceof p){a=o=h}else{a=h[f.prototype.idAttribute||"id"]}if(u=this.get(a)){if(x)_[u.cid]=true;if(w){h=h===o?o.attributes:h;if(e.parse)h=u.parse(h,e);u.set(h,e);if(d&&!l&&u.hasChanged(v))l=true}t[s]=u}else if(b){o=t[s]=this._prepareModel(h,e);if(!o)continue;g.push(o);this._addReference(o,e)}o=u||o;if(E&&(o.isNew()||!_[o.id]))E.push(o);_[o.id]=true}if(x){for(s=0,n=this.length;s<n;++s){if(!_[(o=this.models[s]).cid])y.push(o)}if(y.length)this.remove(y,e)}if(g.length||E&&E.length){if(d)l=true;this.length+=g.length;if(c!=null){for(s=0,n=g.length;s<n;s++){this.models.splice(c+s,0,g[s])}}else{if(E)this.models.length=0;var k=E||g;for(s=0,n=k.length;s<n;s++){this.models.push(k[s])}}}if(l)this.sort({silent:true});if(!e.silent){for(s=0,n=g.length;s<n;s++){(o=g[s]).trigger("add",o,this,e)}if(l||E&&E.length)this.trigger("sort",this,e)}return r?t[0]:t},reset:function(t,e){e||(e={});for(var r=0,s=this.models.length;r<s;r++){this._removeReference(this.models[r],e)}e.previousModels=this.models;this._reset();t=this.add(t,i.extend({silent:true},e));if(!e.silent)this.trigger("reset",this,e);return t},push:function(t,e){return this.add(t,i.extend({at:this.length},e))},pop:function(t){var e=this.at(this.length-1);this.remove(e,t);return e},unshift:function(t,e){return this.add(t,i.extend({at:0},e))},shift:function(t){var e=this.at(0);this.remove(e,t);return e},slice:function(){return o.apply(this.models,arguments)},get:function(t){if(t==null)return void 0;return this._byId[t]||this._byId[t.id]||this._byId[t.cid]},at:function(t){return this.models[t]},where:function(t,e){if(i.isEmpty(t))return e?void 0:[];return this[e?"find":"filter"](function(e){for(var i in t){if(t[i]!==e.get(i))return false}return true})},findWhere:function(t){return this.where(t,true)},sort:function(t){if(!this.comparator)throw new Error("Cannot sort a set without a comparator");t||(t={});if(i.isString(this.comparator)||this.comparator.length===1){this.models=this.sortBy(this.comparator,this)}else{this.models.sort(i.bind(this.comparator,this))}if(!t.silent)this.trigger("sort",this,t);return this},pluck:function(t){return i.invoke(this.models,"get",t)},fetch:function(t){t=t?i.clone(t):{};if(t.parse===void 0)t.parse=true;var e=t.success;var r=this;t.success=function(i){var s=t.reset?"reset":"set";r[s](i,t);if(e)e(r,i,t);r.trigger("sync",r,i,t)};q(this,t);return this.sync("read",this,t)},create:function(t,e){e=e?i.clone(e):{};if(!(t=this._prepareModel(t,e)))return false;if(!e.wait)this.add(t,e);var r=this;var s=e.success;e.success=function(t,i){if(e.wait)r.add(t,e);if(s)s(t,i,e)};t.save(null,e);return t},parse:function(t,e){return t},clone:function(){return new this.constructor(this.models)},_reset:function(){this.length=0;this.models=[];this._byId={}},_prepareModel:function(t,e){if(t instanceof p)return t;e=e?i.clone(e):{};e.collection=this;var r=new this.model(t,e);if(!r.validationError)return r;this.trigger("invalid",this,r.validationError,e);return false},_addReference:function(t,e){this._byId[t.cid]=t;if(t.id!=null)this._byId[t.id]=t;if(!t.collection)t.collection=this;t.on("all",this._onModelEvent,this)},_removeReference:function(t,e){if(this===t.collection)delete t.collection;t.off("all",this._onModelEvent,this)},_onModelEvent:function(t,e,i,r){if((t==="add"||t==="remove")&&i!==this)return;if(t==="destroy")this.remove(e,r);if(e&&t==="change:"+e.idAttribute){delete this._byId[e.previous(e.idAttribute)];if(e.id!=null)this._byId[e.id]=e}this.trigger.apply(this,arguments)}});var _=["forEach","each","map","collect","reduce","foldl","inject","reduceRight","foldr","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","max","min","toArray","size","first","head","take","initial","rest","tail","drop","last","without","difference","indexOf","shuffle","lastIndexOf","isEmpty","chain","sample"];i.each(_,function(t){g.prototype[t]=function(){var e=o.call(arguments);e.unshift(this.models);return i[t].apply(i,e)}});var b=["groupBy","countBy","sortBy","indexBy"];i.each(b,function(t){g.prototype[t]=function(e,r){var s=i.isFunction(e)?e:function(t){return t.get(e)};return i[t](this.models,s,r)}});var w=e.View=function(t){this.cid=i.uniqueId("view");t||(t={});i.extend(this,i.pick(t,E));this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()};var x=/^(\S+)\s*(.*)$/;var E=["model","collection","el","id","attributes","className","tagName","events"];i.extend(w.prototype,u,{tagName:"div",$:function(t){return this.$el.find(t)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();this.stopListening();return this},setElement:function(t,i){if(this.$el)this.undelegateEvents();this.$el=t instanceof e.$?t:e.$(t);this.el=this.$el[0];if(i!==false)this.delegateEvents();return this},delegateEvents:function(t){if(!(t||(t=i.result(this,"events"))))return this;this.undelegateEvents();for(var e in t){var r=t[e];if(!i.isFunction(r))r=this[t[e]];if(!r)continue;var s=e.match(x);var n=s[1],a=s[2];r=i.bind(r,this);n+=".delegateEvents"+this.cid;if(a===""){this.$el.on(n,r)}else{this.$el.on(n,a,r)}}return this},undelegateEvents:function(){this.$el.off(".delegateEvents"+this.cid);return this},_ensureElement:function(){if(!this.el){var t=i.extend({},i.result(this,"attributes"));if(this.id)t.id=i.result(this,"id");if(this.className)t["class"]=i.result(this,"className");var r=e.$("<"+i.result(this,"tagName")+">").attr(t);this.setElement(r,false)}else{this.setElement(i.result(this,"el"),false)}}});e.sync=function(t,r,s){var n=T[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:n,dataType:"json"};if(!s.url){a.url=i.result(r,"url")||M()}if(s.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(s.attrs||r.toJSON(s))}if(s.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(s.emulateHTTP&&(n==="PUT"||n==="DELETE"||n==="PATCH")){a.type="POST";if(s.emulateJSON)a.data._method=n;var o=s.beforeSend;s.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",n);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!s.emulateJSON){a.processData=false}if(a.type==="PATCH"&&k){a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var h=s.xhr=e.ajax(i.extend(a,s));r.trigger("request",r,h,s);return h};var k=typeof window!=="undefined"&&!!window.ActiveXObject&&!(window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent);var T={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var S=/\((.*?)\)/g;var H=/(\(\?)?:\w+/g;var A=/\*\w+/g;var I=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,u,{initialize:function(){},route:function(t,r,s){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){s=r;r=""}if(!s)s=this[r];var n=this;e.history.route(t,function(i){var a=n._extractParameters(t,i);n.execute(s,a);n.trigger.apply(n,["route:"+r].concat(a));n.trigger("route",r,a);e.history.trigger("route",n,r,a)});return this},execute:function(t,e){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(I,"\\$&").replace(S,"(?:$1)?").replace(H,function(t,e){return e?t:"([^/?]+)"}).replace(A,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var N=e.History=function(){this.handlers=[];i.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var R=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var P=/msie [\w.]+/;var C=/\/$/;var j=/#.*$/;N.started=false;i.extend(N.prototype,u,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.slice(i.length)}else{t=this.getHash()}}return t.replace(R,"")},start:function(t){if(N.started)throw new Error("Backbone.history has already been started");N.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var r=this.getFragment();var s=document.documentMode;var n=P.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);this.root=("/"+this.root+"/").replace(O,"/");if(n&&this._wantsHashChange){var a=e.$('<iframe src="javascript:0" tabindex="-1">');this.iframe=a.hide().appendTo("body")[0].contentWindow;this.navigate(r)}if(this._hasPushState){e.$(window).on("popstate",this.checkUrl)}else if(this._wantsHashChange&&"onhashchange"in window&&!n){e.$(window).on("hashchange",this.checkUrl)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}this.fragment=r;var o=this.location;if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){this.fragment=this.getFragment(null,true);this.location.replace(this.root+"#"+this.fragment);return true}else if(this._hasPushState&&this.atRoot()&&o.hash){this.fragment=this.getHash().replace(R,"");this.history.replaceState({},document.title,this.root+this.fragment)}}if(!this.options.silent)return this.loadUrl()},stop:function(){e.$(window).off("popstate",this.checkUrl).off("hashchange",this.checkUrl);if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);N.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getFragment(this.getHash(this.iframe))}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(t){t=this.fragment=this.getFragment(t);return i.any(this.handlers,function(e){if(e.route.test(t)){e.callback(t);return true}})},navigate:function(t,e){if(!N.started)return false;if(!e||e===true)e={trigger:!!e};var i=this.root+(t=this.getFragment(t||""));t=t.replace(j,"");if(this.fragment===t)return;this.fragment=t;if(t===""&&i!=="/")i=i.slice(0,-1);if(this._hasPushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,i)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getFragment(this.getHash(this.iframe))){if(!e.replace)this.iframe.document.open().close();this._updateHash(this.iframe.location,t,e.replace)}}else{return this.location.assign(i)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,"");t.replace(r+"#"+e)}else{t.hash="#"+e}}});e.history=new N;var U=function(t,e){var r=this;var s;if(t&&i.has(t,"constructor")){s=t.constructor}else{s=function(){return r.apply(this,arguments)}}i.extend(s,r,e);var n=function(){this.constructor=s};n.prototype=r.prototype;s.prototype=new n;if(t)i.extend(s.prototype,t);s.__super__=r.prototype;return s};p.extend=g.extend=$.extend=w.extend=N.extend=U;var M=function(){throw new Error('A "url" property or function must be specified')};var q=function(t,e){var i=e.error;e.error=function(r){if(i)i(t,r,e);t.trigger("error",t,r,e)}};return e});
(function(t){var e=typeof self=="object"&&self.self==self&&self||typeof global=="object"&&global.global==global&&global;if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,n){e.Backbone=t(e,n,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore"),r;try{r=require("jquery")}catch(n){}t(e,exports,i,r)}else{e.Backbone=t(e,{},e._,e.jQuery||e.Zepto||e.ender||e.$)}})(function(t,e,i,r){var n=t.Backbone;var s=Array.prototype.slice;e.VERSION="1.2.3";e.$=r;e.noConflict=function(){t.Backbone=n;return this};e.emulateHTTP=false;e.emulateJSON=false;var a=function(t,e,r){switch(t){case 1:return function(){return i[e](this[r])};case 2:return function(t){return i[e](this[r],t)};case 3:return function(t,n){return i[e](this[r],h(t,this),n)};case 4:return function(t,n,s){return i[e](this[r],h(t,this),n,s)};default:return function(){var t=s.call(arguments);t.unshift(this[r]);return i[e].apply(i,t)}}};var o=function(t,e,r){i.each(e,function(e,n){if(i[n])t.prototype[n]=a(e,n,r)})};var h=function(t,e){if(i.isFunction(t))return t;if(i.isObject(t)&&!e._isModel(t))return u(t);if(i.isString(t))return function(e){return e.get(t)};return t};var u=function(t){var e=i.matches(t);return function(t){return e(t.attributes)}};var l=e.Events={};var c=/\s+/;var f=function(t,e,r,n,s){var a=0,o;if(r&&typeof r==="object"){if(n!==void 0&&"context"in s&&s.context===void 0)s.context=n;for(o=i.keys(r);a<o.length;a++){e=f(t,e,o[a],r[o[a]],s)}}else if(r&&c.test(r)){for(o=r.split(c);a<o.length;a++){e=t(e,o[a],n,s)}}else{e=t(e,r,n,s)}return e};l.on=function(t,e,i){return d(this,t,e,i)};var d=function(t,e,i,r,n){t._events=f(v,t._events||{},e,i,{context:r,ctx:t,listening:n});if(n){var s=t._listeners||(t._listeners={});s[n.id]=n}return t};l.listenTo=function(t,e,r){if(!t)return this;var n=t._listenId||(t._listenId=i.uniqueId("l"));var s=this._listeningTo||(this._listeningTo={});var a=s[n];if(!a){var o=this._listenId||(this._listenId=i.uniqueId("l"));a=s[n]={obj:t,objId:n,id:o,listeningTo:s,count:0}}d(t,e,r,this,a);return this};var v=function(t,e,i,r){if(i){var n=t[e]||(t[e]=[]);var s=r.context,a=r.ctx,o=r.listening;if(o)o.count++;n.push({callback:i,context:s,ctx:s||a,listening:o})}return t};l.off=function(t,e,i){if(!this._events)return this;this._events=f(g,this._events,t,e,{context:i,listeners:this._listeners});return this};l.stopListening=function(t,e,r){var n=this._listeningTo;if(!n)return this;var s=t?[t._listenId]:i.keys(n);for(var a=0;a<s.length;a++){var o=n[s[a]];if(!o)break;o.obj.off(e,r,this)}if(i.isEmpty(n))this._listeningTo=void 0;return this};var g=function(t,e,r,n){if(!t)return;var s=0,a;var o=n.context,h=n.listeners;if(!e&&!r&&!o){var u=i.keys(h);for(;s<u.length;s++){a=h[u[s]];delete h[a.id];delete a.listeningTo[a.objId]}return}var l=e?[e]:i.keys(t);for(;s<l.length;s++){e=l[s];var c=t[e];if(!c)break;var f=[];for(var d=0;d<c.length;d++){var v=c[d];if(r&&r!==v.callback&&r!==v.callback._callback||o&&o!==v.context){f.push(v)}else{a=v.listening;if(a&&--a.count===0){delete h[a.id];delete a.listeningTo[a.objId]}}}if(f.length){t[e]=f}else{delete t[e]}}if(i.size(t))return t};l.once=function(t,e,r){var n=f(p,{},t,e,i.bind(this.off,this));return this.on(n,void 0,r)};l.listenToOnce=function(t,e,r){var n=f(p,{},e,r,i.bind(this.stopListening,this,t));return this.listenTo(t,n)};var p=function(t,e,r,n){if(r){var s=t[e]=i.once(function(){n(e,s);r.apply(this,arguments)});s._callback=r}return t};l.trigger=function(t){if(!this._events)return this;var e=Math.max(0,arguments.length-1);var i=Array(e);for(var r=0;r<e;r++)i[r]=arguments[r+1];f(m,this._events,t,void 0,i);return this};var m=function(t,e,i,r){if(t){var n=t[e];var s=t.all;if(n&&s)s=s.slice();if(n)_(n,r);if(s)_(s,[e].concat(r))}return t};var _=function(t,e){var i,r=-1,n=t.length,s=e[0],a=e[1],o=e[2];switch(e.length){case 0:while(++r<n)(i=t[r]).callback.call(i.ctx);return;case 1:while(++r<n)(i=t[r]).callback.call(i.ctx,s);return;case 2:while(++r<n)(i=t[r]).callback.call(i.ctx,s,a);return;case 3:while(++r<n)(i=t[r]).callback.call(i.ctx,s,a,o);return;default:while(++r<n)(i=t[r]).callback.apply(i.ctx,e);return}};l.bind=l.on;l.unbind=l.off;i.extend(e,l);var y=e.Model=function(t,e){var r=t||{};e||(e={});this.cid=i.uniqueId(this.cidPrefix);this.attributes={};if(e.collection)this.collection=e.collection;if(e.parse)r=this.parse(r,e)||{};r=i.defaults({},r,i.result(this,"defaults"));this.set(r,e);this.changed={};this.initialize.apply(this,arguments)};i.extend(y.prototype,l,{changed:null,validationError:null,idAttribute:"id",cidPrefix:"c",initialize:function(){},toJSON:function(t){return i.clone(this.attributes)},sync:function(){return e.sync.apply(this,arguments)},get:function(t){return this.attributes[t]},escape:function(t){return i.escape(this.get(t))},has:function(t){return this.get(t)!=null},matches:function(t){return!!i.iteratee(t,this)(this.attributes)},set:function(t,e,r){if(t==null)return this;var n;if(typeof t==="object"){n=t;r=e}else{(n={})[t]=e}r||(r={});if(!this._validate(n,r))return false;var s=r.unset;var a=r.silent;var o=[];var h=this._changing;this._changing=true;if(!h){this._previousAttributes=i.clone(this.attributes);this.changed={}}var u=this.attributes;var l=this.changed;var c=this._previousAttributes;for(var f in n){e=n[f];if(!i.isEqual(u[f],e))o.push(f);if(!i.isEqual(c[f],e)){l[f]=e}else{delete l[f]}s?delete u[f]:u[f]=e}this.id=this.get(this.idAttribute);if(!a){if(o.length)this._pending=r;for(var d=0;d<o.length;d++){this.trigger("change:"+o[d],this,u[o[d]],r)}}if(h)return this;if(!a){while(this._pending){r=this._pending;this._pending=false;this.trigger("change",this,r)}}this._pending=false;this._changing=false;return this},unset:function(t,e){return this.set(t,void 0,i.extend({},e,{unset:true}))},clear:function(t){var e={};for(var r in this.attributes)e[r]=void 0;return this.set(e,i.extend({},t,{unset:true}))},hasChanged:function(t){if(t==null)return!i.isEmpty(this.changed);return i.has(this.changed,t)},changedAttributes:function(t){if(!t)return this.hasChanged()?i.clone(this.changed):false;var e=this._changing?this._previousAttributes:this.attributes;var r={};for(var n in t){var s=t[n];if(i.isEqual(e[n],s))continue;r[n]=s}return i.size(r)?r:false},previous:function(t){if(t==null||!this._previousAttributes)return null;return this._previousAttributes[t]},previousAttributes:function(){return i.clone(this._previousAttributes)},fetch:function(t){t=i.extend({parse:true},t);var e=this;var r=t.success;t.success=function(i){var n=t.parse?e.parse(i,t):i;if(!e.set(n,t))return false;if(r)r.call(t.context,e,i,t);e.trigger("sync",e,i,t)};z(this,t);return this.sync("read",this,t)},save:function(t,e,r){var n;if(t==null||typeof t==="object"){n=t;r=e}else{(n={})[t]=e}r=i.extend({validate:true,parse:true},r);var s=r.wait;if(n&&!s){if(!this.set(n,r))return false}else{if(!this._validate(n,r))return false}var a=this;var o=r.success;var h=this.attributes;r.success=function(t){a.attributes=h;var e=r.parse?a.parse(t,r):t;if(s)e=i.extend({},n,e);if(e&&!a.set(e,r))return false;if(o)o.call(r.context,a,t,r);a.trigger("sync",a,t,r)};z(this,r);if(n&&s)this.attributes=i.extend({},h,n);var u=this.isNew()?"create":r.patch?"patch":"update";if(u==="patch"&&!r.attrs)r.attrs=n;var l=this.sync(u,this,r);this.attributes=h;return l},destroy:function(t){t=t?i.clone(t):{};var e=this;var r=t.success;var n=t.wait;var s=function(){e.stopListening();e.trigger("destroy",e,e.collection,t)};t.success=function(i){if(n)s();if(r)r.call(t.context,e,i,t);if(!e.isNew())e.trigger("sync",e,i,t)};var a=false;if(this.isNew()){i.defer(t.success)}else{z(this,t);a=this.sync("delete",this,t)}if(!n)s();return a},url:function(){var t=i.result(this,"urlRoot")||i.result(this.collection,"url")||F();if(this.isNew())return t;var e=this.get(this.idAttribute);return t.replace(/[^\/]$/,"$&/")+encodeURIComponent(e)},parse:function(t,e){return t},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.has(this.idAttribute)},isValid:function(t){return this._validate({},i.defaults({validate:true},t))},_validate:function(t,e){if(!e.validate||!this.validate)return true;t=i.extend({},this.attributes,t);var r=this.validationError=this.validate(t,e)||null;if(!r)return true;this.trigger("invalid",this,r,i.extend(e,{validationError:r}));return false}});var b={keys:1,values:1,pairs:1,invert:1,pick:0,omit:0,chain:1,isEmpty:1};o(y,b,"attributes");var x=e.Collection=function(t,e){e||(e={});if(e.model)this.model=e.model;if(e.comparator!==void 0)this.comparator=e.comparator;this._reset();this.initialize.apply(this,arguments);if(t)this.reset(t,i.extend({silent:true},e))};var w={add:true,remove:true,merge:true};var E={add:true,remove:false};var k=function(t,e,i){i=Math.min(Math.max(i,0),t.length);var r=Array(t.length-i);var n=e.length;for(var s=0;s<r.length;s++)r[s]=t[s+i];for(s=0;s<n;s++)t[s+i]=e[s];for(s=0;s<r.length;s++)t[s+n+i]=r[s]};i.extend(x.prototype,l,{model:y,initialize:function(){},toJSON:function(t){return this.map(function(e){return e.toJSON(t)})},sync:function(){return e.sync.apply(this,arguments)},add:function(t,e){return this.set(t,i.extend({merge:false},e,E))},remove:function(t,e){e=i.extend({},e);var r=!i.isArray(t);t=r?[t]:i.clone(t);var n=this._removeModels(t,e);if(!e.silent&&n)this.trigger("update",this,e);return r?n[0]:n},set:function(t,e){if(t==null)return;e=i.defaults({},e,w);if(e.parse&&!this._isModel(t))t=this.parse(t,e);var r=!i.isArray(t);t=r?[t]:t.slice();var n=e.at;if(n!=null)n=+n;if(n<0)n+=this.length+1;var s=[];var a=[];var o=[];var h={};var u=e.add;var l=e.merge;var c=e.remove;var f=false;var d=this.comparator&&n==null&&e.sort!==false;var v=i.isString(this.comparator)?this.comparator:null;var g;for(var p=0;p<t.length;p++){g=t[p];var m=this.get(g);if(m){if(l&&g!==m){var _=this._isModel(g)?g.attributes:g;if(e.parse)_=m.parse(_,e);m.set(_,e);if(d&&!f)f=m.hasChanged(v)}if(!h[m.cid]){h[m.cid]=true;s.push(m)}t[p]=m}else if(u){g=t[p]=this._prepareModel(g,e);if(g){a.push(g);this._addReference(g,e);h[g.cid]=true;s.push(g)}}}if(c){for(p=0;p<this.length;p++){g=this.models[p];if(!h[g.cid])o.push(g)}if(o.length)this._removeModels(o,e)}var y=false;var b=!d&&u&&c;if(s.length&&b){y=this.length!=s.length||i.some(this.models,function(t,e){return t!==s[e]});this.models.length=0;k(this.models,s,0);this.length=this.models.length}else if(a.length){if(d)f=true;k(this.models,a,n==null?this.length:n);this.length=this.models.length}if(f)this.sort({silent:true});if(!e.silent){for(p=0;p<a.length;p++){if(n!=null)e.index=n+p;g=a[p];g.trigger("add",g,this,e)}if(f||y)this.trigger("sort",this,e);if(a.length||o.length)this.trigger("update",this,e)}return r?t[0]:t},reset:function(t,e){e=e?i.clone(e):{};for(var r=0;r<this.models.length;r++){this._removeReference(this.models[r],e)}e.previousModels=this.models;this._reset();t=this.add(t,i.extend({silent:true},e));if(!e.silent)this.trigger("reset",this,e);return t},push:function(t,e){return this.add(t,i.extend({at:this.length},e))},pop:function(t){var e=this.at(this.length-1);return this.remove(e,t)},unshift:function(t,e){return this.add(t,i.extend({at:0},e))},shift:function(t){var e=this.at(0);return this.remove(e,t)},slice:function(){return s.apply(this.models,arguments)},get:function(t){if(t==null)return void 0;var e=this.modelId(this._isModel(t)?t.attributes:t);return this._byId[t]||this._byId[e]||this._byId[t.cid]},at:function(t){if(t<0)t+=this.length;return this.models[t]},where:function(t,e){return this[e?"find":"filter"](t)},findWhere:function(t){return this.where(t,true)},sort:function(t){var e=this.comparator;if(!e)throw new Error("Cannot sort a set without a comparator");t||(t={});var r=e.length;if(i.isFunction(e))e=i.bind(e,this);if(r===1||i.isString(e)){this.models=this.sortBy(e)}else{this.models.sort(e)}if(!t.silent)this.trigger("sort",this,t);return this},pluck:function(t){return i.invoke(this.models,"get",t)},fetch:function(t){t=i.extend({parse:true},t);var e=t.success;var r=this;t.success=function(i){var n=t.reset?"reset":"set";r[n](i,t);if(e)e.call(t.context,r,i,t);r.trigger("sync",r,i,t)};z(this,t);return this.sync("read",this,t)},create:function(t,e){e=e?i.clone(e):{};var r=e.wait;t=this._prepareModel(t,e);if(!t)return false;if(!r)this.add(t,e);var n=this;var s=e.success;e.success=function(t,e,i){if(r)n.add(t,i);if(s)s.call(i.context,t,e,i)};t.save(null,e);return t},parse:function(t,e){return t},clone:function(){return new this.constructor(this.models,{model:this.model,comparator:this.comparator})},modelId:function(t){return t[this.model.prototype.idAttribute||"id"]},_reset:function(){this.length=0;this.models=[];this._byId={}},_prepareModel:function(t,e){if(this._isModel(t)){if(!t.collection)t.collection=this;return t}e=e?i.clone(e):{};e.collection=this;var r=new this.model(t,e);if(!r.validationError)return r;this.trigger("invalid",this,r.validationError,e);return false},_removeModels:function(t,e){var i=[];for(var r=0;r<t.length;r++){var n=this.get(t[r]);if(!n)continue;var s=this.indexOf(n);this.models.splice(s,1);this.length--;if(!e.silent){e.index=s;n.trigger("remove",n,this,e)}i.push(n);this._removeReference(n,e)}return i.length?i:false},_isModel:function(t){return t instanceof y},_addReference:function(t,e){this._byId[t.cid]=t;var i=this.modelId(t.attributes);if(i!=null)this._byId[i]=t;t.on("all",this._onModelEvent,this)},_removeReference:function(t,e){delete this._byId[t.cid];var i=this.modelId(t.attributes);if(i!=null)delete this._byId[i];if(this===t.collection)delete t.collection;t.off("all",this._onModelEvent,this)},_onModelEvent:function(t,e,i,r){if((t==="add"||t==="remove")&&i!==this)return;if(t==="destroy")this.remove(e,r);if(t==="change"){var n=this.modelId(e.previousAttributes());var s=this.modelId(e.attributes);if(n!==s){if(n!=null)delete this._byId[n];if(s!=null)this._byId[s]=e}}this.trigger.apply(this,arguments)}});var S={forEach:3,each:3,map:3,collect:3,reduce:4,foldl:4,inject:4,reduceRight:4,foldr:4,find:3,detect:3,filter:3,select:3,reject:3,every:3,all:3,some:3,any:3,include:3,includes:3,contains:3,invoke:0,max:3,min:3,toArray:1,size:1,first:3,head:3,take:3,initial:3,rest:3,tail:3,drop:3,last:3,without:0,difference:0,indexOf:3,shuffle:1,lastIndexOf:3,isEmpty:1,chain:1,sample:3,partition:3,groupBy:3,countBy:3,sortBy:3,indexBy:3};o(x,S,"models");var I=e.View=function(t){this.cid=i.uniqueId("view");i.extend(this,i.pick(t,P));this._ensureElement();this.initialize.apply(this,arguments)};var T=/^(\S+)\s*(.*)$/;var P=["model","collection","el","id","attributes","className","tagName","events"];i.extend(I.prototype,l,{tagName:"div",$:function(t){return this.$el.find(t)},initialize:function(){},render:function(){return this},remove:function(){this._removeElement();this.stopListening();return this},_removeElement:function(){this.$el.remove()},setElement:function(t){this.undelegateEvents();this._setElement(t);this.delegateEvents();return this},_setElement:function(t){this.$el=t instanceof e.$?t:e.$(t);this.el=this.$el[0]},delegateEvents:function(t){t||(t=i.result(this,"events"));if(!t)return this;this.undelegateEvents();for(var e in t){var r=t[e];if(!i.isFunction(r))r=this[r];if(!r)continue;var n=e.match(T);this.delegate(n[1],n[2],i.bind(r,this))}return this},delegate:function(t,e,i){this.$el.on(t+".delegateEvents"+this.cid,e,i);return this},undelegateEvents:function(){if(this.$el)this.$el.off(".delegateEvents"+this.cid);return this},undelegate:function(t,e,i){this.$el.off(t+".delegateEvents"+this.cid,e,i);return this},_createElement:function(t){return document.createElement(t)},_ensureElement:function(){if(!this.el){var t=i.extend({},i.result(this,"attributes"));if(this.id)t.id=i.result(this,"id");if(this.className)t["class"]=i.result(this,"className");this.setElement(this._createElement(i.result(this,"tagName")));this._setAttributes(t)}else{this.setElement(i.result(this,"el"))}},_setAttributes:function(t){this.$el.attr(t)}});e.sync=function(t,r,n){var s=H[t];i.defaults(n||(n={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:s,dataType:"json"};if(!n.url){a.url=i.result(r,"url")||F()}if(n.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(n.attrs||r.toJSON(n))}if(n.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(n.emulateHTTP&&(s==="PUT"||s==="DELETE"||s==="PATCH")){a.type="POST";if(n.emulateJSON)a.data._method=s;var o=n.beforeSend;n.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",s);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!n.emulateJSON){a.processData=false}var h=n.error;n.error=function(t,e,i){n.textStatus=e;n.errorThrown=i;if(h)h.call(n.context,t,e,i)};var u=n.xhr=e.ajax(i.extend(a,n));r.trigger("request",r,u,n);return u};var H={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var A=/\((.*?)\)/g;var C=/(\(\?)?:\w+/g;var R=/\*\w+/g;var j=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,l,{initialize:function(){},route:function(t,r,n){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){n=r;r=""}if(!n)n=this[r];var s=this;e.history.route(t,function(i){var a=s._extractParameters(t,i);if(s.execute(n,a,r)!==false){s.trigger.apply(s,["route:"+r].concat(a));s.trigger("route",r,a);e.history.trigger("route",s,r,a)}});return this},execute:function(t,e,i){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(j,"\\$&").replace(A,"(?:$1)?").replace(C,function(t,e){return e?t:"([^/?]+)"}).replace(R,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var M=e.History=function(){this.handlers=[];this.checkUrl=i.bind(this.checkUrl,this);if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var N=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var U=/#.*$/;M.started=false;i.extend(M.prototype,l,{interval:50,atRoot:function(){var t=this.location.pathname.replace(/[^\/]$/,"$&/");return t===this.root&&!this.getSearch()},matchRoot:function(){var t=this.decodeFragment(this.location.pathname);var e=t.slice(0,this.root.length-1)+"/";return e===this.root},decodeFragment:function(t){return decodeURI(t.replace(/%25/g,"%2525"))},getSearch:function(){var t=this.location.href.replace(/#.*/,"").match(/\?.+/);return t?t[0]:""},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getPath:function(){var t=this.decodeFragment(this.location.pathname+this.getSearch()).slice(this.root.length-1);return t.charAt(0)==="/"?t.slice(1):t},getFragment:function(t){if(t==null){if(this._usePushState||!this._wantsHashChange){t=this.getPath()}else{t=this.getHash()}}return t.replace(N,"")},start:function(t){if(M.started)throw new Error("Backbone.history has already been started");M.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._hasHashChange="onhashchange"in window&&(document.documentMode===void 0||document.documentMode>7);this._useHashChange=this._wantsHashChange&&this._hasHashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.history&&this.history.pushState);this._usePushState=this._wantsPushState&&this._hasPushState;this.fragment=this.getFragment();this.root=("/"+this.root+"/").replace(O,"/");if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){var e=this.root.slice(0,-1)||"/";this.location.replace(e+"#"+this.getPath());return true}else if(this._hasPushState&&this.atRoot()){this.navigate(this.getHash(),{replace:true})}}if(!this._hasHashChange&&this._wantsHashChange&&!this._usePushState){this.iframe=document.createElement("iframe");this.iframe.src="javascript:0";this.iframe.style.display="none";this.iframe.tabIndex=-1;var r=document.body;var n=r.insertBefore(this.iframe,r.firstChild).contentWindow;n.document.open();n.document.close();n.location.hash="#"+this.fragment}var s=window.addEventListener||function(t,e){return attachEvent("on"+t,e)};if(this._usePushState){s("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){s("hashchange",this.checkUrl,false)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}if(!this.options.silent)return this.loadUrl()},stop:function(){var t=window.removeEventListener||function(t,e){return detachEvent("on"+t,e)};if(this._usePushState){t("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){t("hashchange",this.checkUrl,false)}if(this.iframe){document.body.removeChild(this.iframe);this.iframe=null}if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);M.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getHash(this.iframe.contentWindow)}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(t){if(!this.matchRoot())return false;t=this.fragment=this.getFragment(t);return i.some(this.handlers,function(e){if(e.route.test(t)){e.callback(t);return true}})},navigate:function(t,e){if(!M.started)return false;if(!e||e===true)e={trigger:!!e};t=this.getFragment(t||"");var i=this.root;if(t===""||t.charAt(0)==="?"){i=i.slice(0,-1)||"/"}var r=i+t;t=this.decodeFragment(t.replace(U,""));if(this.fragment===t)return;this.fragment=t;if(this._usePushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,r)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getHash(this.iframe.contentWindow)){var n=this.iframe.contentWindow;if(!e.replace){n.document.open();n.document.close()}this._updateHash(n.location,t,e.replace)}}else{return this.location.assign(r)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,"");t.replace(r+"#"+e)}else{t.hash="#"+e}}});e.history=new M;var q=function(t,e){var r=this;var n;if(t&&i.has(t,"constructor")){n=t.constructor}else{n=function(){return r.apply(this,arguments)}}i.extend(n,r,e);var s=function(){this.constructor=n};s.prototype=r.prototype;n.prototype=new s;if(t)i.extend(n.prototype,t);n.__super__=r.prototype;return n};y.extend=x.extend=$.extend=I.extend=M.extend=q;var F=function(){throw new Error('A "url" property or function must be specified')};var z=function(t,e){var i=e.error;e.error=function(r){if(i)i.call(e.context,t,r,e);t.trigger("error",t,r,e)}};return e});
//# sourceMappingURL=backbone-min.map
\ No newline at end of file
{"version":3,"file":"backbone-min.js","sources":["backbone.js"],"names":["factory","root","self","global","define","amd","_","$","exports","Backbone","require","e","jQuery","Zepto","ender","previousBackbone","slice","Array","prototype","VERSION","noConflict","this","emulateHTTP","emulateJSON","addMethod","length","method","attribute","value","iteratee","context","cb","defaultVal","args","call","arguments","unshift","apply","addUnderscoreMethods","Class","methods","each","instance","isFunction","isObject","_isModel","modelMatcher","isString","model","get","attrs","matcher","matches","attributes","Events","eventSplitter","eventsApi","events","name","callback","opts","i","names","keys","test","split","on","internalOn","obj","listening","_events","onApi","ctx","listeners","_listeners","id","listenTo","_listenId","uniqueId","listeningTo","_listeningTo","thisId","objId","count","options","handlers","push","off","offApi","stopListening","ids","isEmpty","remaining","j","handler","_callback","size","once","onceMap","bind","listenToOnce","map","offer","trigger","Math","max","triggerApi","objEvents","allEvents","all","triggerEvents","concat","ev","l","a1","a2","a3","unbind","extend","Model","cid","cidPrefix","collection","parse","defaults","result","set","changed","initialize","validationError","idAttribute","toJSON","clone","sync","attr","escape","has","key","val","_validate","unset","silent","changes","changing","_changing","_previousAttributes","current","prev","isEqual","_pending","clear","hasChanged","changedAttributes","diff","old","previous","previousAttributes","fetch","success","resp","serverAttrs","wrapError","save","validate","wait","isNew","patch","xhr","destroy","defer","url","base","urlError","replace","encodeURIComponent","constructor","isValid","error","modelMethods","values","pairs","invert","pick","omit","chain","Collection","models","comparator","_reset","reset","setOptions","add","remove","merge","addOptions","splice","array","insert","at","min","tail","singular","isArray","removed","_removeModels","toAdd","toRemove","modelMap","sort","sortable","sortAttr","existing","_prepareModel","_addReference","orderChanged","some","index","_removeReference","previousModels","pop","shift","modelId","_byId","where","first","findWhere","Error","sortBy","pluck","invoke","create","callbackOpts","indexOf","_onModelEvent","event","prevId","collectionMethods","forEach","collect","reduce","foldl","inject","reduceRight","foldr","find","detect","filter","select","reject","every","any","include","includes","contains","toArray","head","take","initial","rest","drop","last","without","difference","shuffle","lastIndexOf","sample","partition","groupBy","countBy","indexBy","View","viewOptions","_ensureElement","delegateEventSplitter","tagName","selector","$el","render","_removeElement","setElement","element","undelegateEvents","_setElement","delegateEvents","el","match","delegate","eventName","listener","undelegate","_createElement","document","createElement","className","_setAttributes","type","methodMap","params","dataType","data","contentType","JSON","stringify","_method","beforeSend","setRequestHeader","processData","textStatus","errorThrown","ajax","update","delete","read","Router","routes","_bindRoutes","optionalParam","namedParam","splatParam","escapeRegExp","route","isRegExp","_routeToRegExp","router","history","fragment","_extractParameters","execute","navigate","optional","RegExp","exec","param","decodeURIComponent","History","checkUrl","window","location","routeStripper","rootStripper","pathStripper","started","interval","atRoot","path","pathname","getSearch","matchRoot","decodeFragment","decodeURI","href","getHash","getPath","charAt","getFragment","_usePushState","_wantsHashChange","start","hashChange","_hasHashChange","documentMode","_useHashChange","_wantsPushState","pushState","_hasPushState","iframe","src","style","display","tabIndex","body","iWindow","insertBefore","firstChild","contentWindow","open","close","hash","addEventListener","attachEvent","_checkUrlInterval","setInterval","loadUrl","stop","removeEventListener","detachEvent","removeChild","clearInterval","title","_updateHash","assign","protoProps","staticProps","parent","child","Surrogate","__super__"],"mappings":"CAOC,SAASA,GAIR,GAAIC,SAAeC,OAAQ,UAAYA,KAAKA,MAAQA,MAAQA,YAC1CC,SAAU,UAAYA,OAAOA,QAAUA,QAAUA,MAGnE,UAAWC,UAAW,YAAcA,OAAOC,IAAK,CAC9CD,QAAQ,aAAc,SAAU,WAAY,SAASE,EAAGC,EAAGC,GAGzDP,EAAKQ,SAAWT,EAAQC,EAAMO,EAASF,EAAGC,SAIvC,UAAWC,WAAY,YAAa,CACzC,GAAIF,GAAII,QAAQ,cAAeH,CAC/B,KAAMA,EAAIG,QAAQ,UAAa,MAAMC,IACrCX,EAAQC,EAAMO,QAASF,EAAGC,OAGrB,CACLN,EAAKQ,SAAWT,EAAQC,KAAUA,EAAKK,EAAIL,EAAKW,QAAUX,EAAKY,OAASZ,EAAKa,OAASb,EAAKM,MAG7F,SAASN,EAAMQ,EAAUH,EAAGC,GAO5B,GAAIQ,GAAmBd,EAAKQ,QAG5B,IAAIO,GAAQC,MAAMC,UAAUF,KAG5BP,GAASU,QAAU,OAInBV,GAASF,EAAIA,CAIbE,GAASW,WAAa,WACpBnB,EAAKQ,SAAWM,CAChB,OAAOM,MAMTZ,GAASa,YAAc,KAMvBb,GAASc,YAAc,KASvB,IAAIC,GAAY,SAASC,EAAQC,EAAQC,GACvC,OAAQF,GACN,IAAK,GAAG,MAAO,YACb,MAAOnB,GAAEoB,GAAQL,KAAKM,IAExB,KAAK,GAAG,MAAO,UAASC,GACtB,MAAOtB,GAAEoB,GAAQL,KAAKM,GAAYC,GAEpC,KAAK,GAAG,MAAO,UAASC,EAAUC,GAChC,MAAOxB,GAAEoB,GAAQL,KAAKM,GAAYI,EAAGF,EAAUR,MAAOS,GAExD,KAAK,GAAG,MAAO,UAASD,EAAUG,EAAYF,GAC5C,MAAOxB,GAAEoB,GAAQL,KAAKM,GAAYI,EAAGF,EAAUR,MAAOW,EAAYF,GAEpE,SAAS,MAAO,YACd,GAAIG,GAAOjB,EAAMkB,KAAKC,UACtBF,GAAKG,QAAQf,KAAKM,GAClB,OAAOrB,GAAEoB,GAAQW,MAAM/B,EAAG2B,KAIhC,IAAIK,GAAuB,SAASC,EAAOC,EAASb,GAClDrB,EAAEmC,KAAKD,EAAS,SAASf,EAAQC,GAC/B,GAAIpB,EAAEoB,GAASa,EAAMrB,UAAUQ,GAAUF,EAAUC,EAAQC,EAAQC,KAKvE,IAAII,GAAK,SAASF,EAAUa,GAC1B,GAAIpC,EAAEqC,WAAWd,GAAW,MAAOA,EACnC,IAAIvB,EAAEsC,SAASf,KAAca,EAASG,SAAShB,GAAW,MAAOiB,GAAajB,EAC9E,IAAIvB,EAAEyC,SAASlB,GAAW,MAAO,UAASmB,GAAS,MAAOA,GAAMC,IAAIpB,GACpE,OAAOA,GAET,IAAIiB,GAAe,SAASI,GAC1B,GAAIC,GAAU7C,EAAE8C,QAAQF,EACxB,OAAO,UAASF,GACd,MAAOG,GAAQH,EAAMK,aAiBzB,IAAIC,GAAS7C,EAAS6C,SAGtB,IAAIC,GAAgB,KAKpB,IAAIC,GAAY,SAAS3B,EAAU4B,EAAQC,EAAMC,EAAUC,GACzD,GAAIC,GAAI,EAAGC,CACX,IAAIJ,SAAeA,KAAS,SAAU,CAEpC,GAAIC,QAAkB,IAAK,WAAaC,IAAQA,EAAK9B,cAAiB,GAAG8B,EAAK9B,QAAU6B,CACxF,KAAKG,EAAQxD,EAAEyD,KAAKL,GAAOG,EAAIC,EAAMrC,OAASoC,IAAK,CACjDJ,EAASD,EAAU3B,EAAU4B,EAAQK,EAAMD,GAAIH,EAAKI,EAAMD,IAAKD,QAE5D,IAAIF,GAAQH,EAAcS,KAAKN,GAAO,CAE3C,IAAKI,EAAQJ,EAAKO,MAAMV,GAAgBM,EAAIC,EAAMrC,OAAQoC,IAAK,CAC7DJ,EAAS5B,EAAS4B,EAAQK,EAAMD,GAAIF,EAAUC,QAE3C,CAELH,EAAS5B,EAAS4B,EAAQC,EAAMC,EAAUC,GAE5C,MAAOH,GAKTH,GAAOY,GAAK,SAASR,EAAMC,EAAU7B,GACnC,MAAOqC,GAAW9C,KAAMqC,EAAMC,EAAU7B,GAI1C,IAAIqC,GAAa,SAASC,EAAKV,EAAMC,EAAU7B,EAASuC,GACtDD,EAAIE,QAAUd,EAAUe,EAAOH,EAAIE,YAAeZ,EAAMC,GACpD7B,QAASA,EACT0C,IAAKJ,EACLC,UAAWA,GAGf,IAAIA,EAAW,CACb,GAAII,GAAYL,EAAIM,aAAeN,EAAIM,cACvCD,GAAUJ,EAAUM,IAAMN,EAG5B,MAAOD,GAMTd,GAAOsB,SAAY,SAASR,EAAKV,EAAMC,GACrC,IAAKS,EAAK,MAAO/C,KACjB,IAAIsD,GAAKP,EAAIS,YAAcT,EAAIS,UAAYvE,EAAEwE,SAAS,KACtD,IAAIC,GAAc1D,KAAK2D,eAAiB3D,KAAK2D,gBAC7C,IAAIX,GAAYU,EAAYJ,EAI5B,KAAKN,EAAW,CACd,GAAIY,GAAS5D,KAAKwD,YAAcxD,KAAKwD,UAAYvE,EAAEwE,SAAS,KAC5DT,GAAYU,EAAYJ,IAAOP,IAAKA,EAAKc,MAAOP,EAAIA,GAAIM,EAAQF,YAAaA,EAAaI,MAAO,GAInGhB,EAAWC,EAAKV,EAAMC,EAAUtC,KAAMgD,EACtC,OAAOhD,MAIT,IAAIkD,GAAQ,SAASd,EAAQC,EAAMC,EAAUyB,GAC3C,GAAIzB,EAAU,CACZ,GAAI0B,GAAW5B,EAAOC,KAAUD,EAAOC,MACvC,IAAI5B,GAAUsD,EAAQtD,QAAS0C,EAAMY,EAAQZ,IAAKH,EAAYe,EAAQf,SACtE,IAAIA,EAAWA,EAAUc,OAEzBE,GAASC,MAAO3B,SAAUA,EAAU7B,QAASA,EAAS0C,IAAK1C,GAAW0C,EAAKH,UAAWA,IAExF,MAAOZ,GAOTH,GAAOiC,IAAO,SAAS7B,EAAMC,EAAU7B,GACrC,IAAKT,KAAKiD,QAAS,MAAOjD,KAC1BA,MAAKiD,QAAUd,EAAUgC,EAAQnE,KAAKiD,QAASZ,EAAMC,GACjD7B,QAASA,EACT2C,UAAWpD,KAAKqD,YAEpB,OAAOrD,MAKTiC,GAAOmC,cAAiB,SAASrB,EAAKV,EAAMC,GAC1C,GAAIoB,GAAc1D,KAAK2D,YACvB,KAAKD,EAAa,MAAO1D,KAEzB,IAAIqE,GAAMtB,GAAOA,EAAIS,WAAavE,EAAEyD,KAAKgB,EAEzC,KAAK,GAAIlB,GAAI,EAAGA,EAAI6B,EAAIjE,OAAQoC,IAAK,CACnC,GAAIQ,GAAYU,EAAYW,EAAI7B,GAIhC,KAAKQ,EAAW,KAEhBA,GAAUD,IAAImB,IAAI7B,EAAMC,EAAUtC,MAEpC,GAAIf,EAAEqF,QAAQZ,GAAc1D,KAAK2D,iBAAoB,EAErD,OAAO3D,MAIT,IAAImE,GAAS,SAAS/B,EAAQC,EAAMC,EAAUyB,GAC5C,IAAK3B,EAAQ,MAEb,IAAII,GAAI,EAAGQ,CACX,IAAIvC,GAAUsD,EAAQtD,QAAS2C,EAAYW,EAAQX,SAGnD,KAAKf,IAASC,IAAa7B,EAAS,CAClC,GAAI4D,GAAMpF,EAAEyD,KAAKU,EACjB,MAAOZ,EAAI6B,EAAIjE,OAAQoC,IAAK,CAC1BQ,EAAYI,EAAUiB,EAAI7B,UACnBY,GAAUJ,EAAUM,UACpBN,GAAUU,YAAYV,EAAUa,OAEzC,OAGF,GAAIpB,GAAQJ,GAAQA,GAAQpD,EAAEyD,KAAKN,EACnC,MAAOI,EAAIC,EAAMrC,OAAQoC,IAAK,CAC5BH,EAAOI,EAAMD,EACb,IAAIwB,GAAW5B,EAAOC,EAGtB,KAAK2B,EAAU,KAGf,IAAIO,KACJ,KAAK,GAAIC,GAAI,EAAGA,EAAIR,EAAS5D,OAAQoE,IAAK,CACxC,GAAIC,GAAUT,EAASQ,EACvB,IACElC,GAAYA,IAAamC,EAAQnC,UAC/BA,IAAamC,EAAQnC,SAASoC,WAC5BjE,GAAWA,IAAYgE,EAAQhE,QACnC,CACA8D,EAAUN,KAAKQ,OACV,CACLzB,EAAYyB,EAAQzB,SACpB,IAAIA,KAAeA,EAAUc,QAAU,EAAG,OACjCV,GAAUJ,EAAUM,UACpBN,GAAUU,YAAYV,EAAUa,SAM7C,GAAIU,EAAUnE,OAAQ,CACpBgC,EAAOC,GAAQkC,MACV,OACEnC,GAAOC,IAGlB,GAAIpD,EAAE0F,KAAKvC,GAAS,MAAOA,GAO7BH,GAAO2C,KAAQ,SAASvC,EAAMC,EAAU7B,GAEtC,GAAI2B,GAASD,EAAU0C,KAAaxC,EAAMC,EAAUrD,EAAE6F,KAAK9E,KAAKkE,IAAKlE,MACrE,OAAOA,MAAK6C,GAAGT,MAAa,GAAG3B,GAIjCwB,GAAO8C,aAAgB,SAAShC,EAAKV,EAAMC,GAEzC,GAAIF,GAASD,EAAU0C,KAAaxC,EAAMC,EAAUrD,EAAE6F,KAAK9E,KAAKoE,cAAepE,KAAM+C,GACrF,OAAO/C,MAAKuD,SAASR,EAAKX,GAK5B,IAAIyC,GAAU,SAASG,EAAK3C,EAAMC,EAAU2C,GAC1C,GAAI3C,EAAU,CACZ,GAAIsC,GAAOI,EAAI3C,GAAQpD,EAAE2F,KAAK,WAC5BK,EAAM5C,EAAMuC,EACZtC,GAAStB,MAAMhB,KAAMc,YAEvB8D,GAAKF,UAAYpC,EAEnB,MAAO0C,GAOT/C,GAAOiD,QAAW,SAAS7C,GACzB,IAAKrC,KAAKiD,QAAS,MAAOjD,KAE1B,IAAII,GAAS+E,KAAKC,IAAI,EAAGtE,UAAUV,OAAS,EAC5C,IAAIQ,GAAOhB,MAAMQ,EACjB,KAAK,GAAIoC,GAAI,EAAGA,EAAIpC,EAAQoC,IAAK5B,EAAK4B,GAAK1B,UAAU0B,EAAI,EAEzDL,GAAUkD,EAAYrF,KAAKiD,QAASZ,MAAW,GAAGzB,EAClD,OAAOZ,MAIT,IAAIqF,GAAa,SAASC,EAAWjD,EAAM3B,EAAIE,GAC7C,GAAI0E,EAAW,CACb,GAAIlD,GAASkD,EAAUjD,EACvB,IAAIkD,GAAYD,EAAUE,GAC1B,IAAIpD,GAAUmD,EAAWA,EAAYA,EAAU5F,OAC/C,IAAIyC,EAAQqD,EAAcrD,EAAQxB,EAClC,IAAI2E,EAAWE,EAAcF,GAAYlD,GAAMqD,OAAO9E,IAExD,MAAO0E,GAMT,IAAIG,GAAgB,SAASrD,EAAQxB,GACnC,GAAI+E,GAAInD,GAAK,EAAGoD,EAAIxD,EAAOhC,OAAQyF,EAAKjF,EAAK,GAAIkF,EAAKlF,EAAK,GAAImF,EAAKnF,EAAK,EACzE,QAAQA,EAAKR,QACX,IAAK,GAAG,QAASoC,EAAIoD,GAAID,EAAKvD,EAAOI,IAAIF,SAASzB,KAAK8E,EAAGxC,IAAM,OAChE,KAAK,GAAG,QAASX,EAAIoD,GAAID,EAAKvD,EAAOI,IAAIF,SAASzB,KAAK8E,EAAGxC,IAAK0C,EAAK,OACpE,KAAK,GAAG,QAASrD,EAAIoD,GAAID,EAAKvD,EAAOI,IAAIF,SAASzB,KAAK8E,EAAGxC,IAAK0C,EAAIC,EAAK,OACxE,KAAK,GAAG,QAAStD,EAAIoD,GAAID,EAAKvD,EAAOI,IAAIF,SAASzB,KAAK8E,EAAGxC,IAAK0C,EAAIC,EAAIC,EAAK,OAC5E,SAAS,QAASvD,EAAIoD,GAAID,EAAKvD,EAAOI,IAAIF,SAAStB,MAAM2E,EAAGxC,IAAKvC,EAAO,SAK5EqB,GAAO6C,KAAS7C,EAAOY,EACvBZ,GAAO+D,OAAS/D,EAAOiC,GAIvBjF,GAAEgH,OAAO7G,EAAU6C,EAYnB,IAAIiE,GAAQ9G,EAAS8G,MAAQ,SAASlE,EAAY+B,GAChD,GAAIlC,GAAQG,KACZ+B,KAAYA,KACZ/D,MAAKmG,IAAMlH,EAAEwE,SAASzD,KAAKoG,UAC3BpG,MAAKgC,aACL,IAAI+B,EAAQsC,WAAYrG,KAAKqG,WAAatC,EAAQsC,UAClD,IAAItC,EAAQuC,MAAOzE,EAAQ7B,KAAKsG,MAAMzE,EAAOkC,MAC7ClC,GAAQ5C,EAAEsH,YAAa1E,EAAO5C,EAAEuH,OAAOxG,KAAM,YAC7CA,MAAKyG,IAAI5E,EAAOkC,EAChB/D,MAAK0G,UACL1G,MAAK2G,WAAW3F,MAAMhB,KAAMc,WAI9B7B,GAAEgH,OAAOC,EAAMrG,UAAWoC,GAGxByE,QAAS,KAGTE,gBAAiB,KAIjBC,YAAa,KAIbT,UAAW,IAIXO,WAAY,aAGZG,OAAQ,SAAS/C,GACf,MAAO9E,GAAE8H,MAAM/G,KAAKgC,aAKtBgF,KAAM,WACJ,MAAO5H,GAAS4H,KAAKhG,MAAMhB,KAAMc,YAInCc,IAAK,SAASqF,GACZ,MAAOjH,MAAKgC,WAAWiF,IAIzBC,OAAQ,SAASD,GACf,MAAOhI,GAAEiI,OAAOlH,KAAK4B,IAAIqF,KAK3BE,IAAK,SAASF,GACZ,MAAOjH,MAAK4B,IAAIqF,IAAS,MAI3BlF,QAAS,SAASF,GAChB,QAAS5C,EAAEuB,SAASqB,EAAO7B,MAAMA,KAAKgC,aAMxCyE,IAAK,SAASW,EAAKC,EAAKtD,GACtB,GAAIqD,GAAO,KAAM,MAAOpH,KAGxB,IAAI6B,EACJ,UAAWuF,KAAQ,SAAU,CAC3BvF,EAAQuF,CACRrD,GAAUsD,MACL,EACJxF,MAAYuF,GAAOC,EAGtBtD,IAAYA,KAGZ,KAAK/D,KAAKsH,UAAUzF,EAAOkC,GAAU,MAAO,MAG5C,IAAIwD,GAAaxD,EAAQwD,KACzB,IAAIC,GAAazD,EAAQyD,MACzB,IAAIC,KACJ,IAAIC,GAAa1H,KAAK2H,SACtB3H,MAAK2H,UAAY,IAEjB,KAAKD,EAAU,CACb1H,KAAK4H,oBAAsB3I,EAAE8H,MAAM/G,KAAKgC,WACxChC,MAAK0G,WAGP,GAAImB,GAAU7H,KAAKgC,UACnB,IAAI0E,GAAU1G,KAAK0G,OACnB,IAAIoB,GAAU9H,KAAK4H,mBAGnB,KAAK,GAAIX,KAAQpF,GAAO,CACtBwF,EAAMxF,EAAMoF,EACZ,KAAKhI,EAAE8I,QAAQF,EAAQZ,GAAOI,GAAMI,EAAQxD,KAAKgD,EACjD,KAAKhI,EAAE8I,QAAQD,EAAKb,GAAOI,GAAM,CAC/BX,EAAQO,GAAQI,MACX,OACEX,GAAQO,GAEjBM,QAAeM,GAAQZ,GAAQY,EAAQZ,GAAQI,EAIjDrH,KAAKsD,GAAKtD,KAAK4B,IAAI5B,KAAK6G,YAGxB,KAAKW,EAAQ,CACX,GAAIC,EAAQrH,OAAQJ,KAAKgI,SAAWjE,CACpC,KAAK,GAAIvB,GAAI,EAAGA,EAAIiF,EAAQrH,OAAQoC,IAAK,CACvCxC,KAAKkF,QAAQ,UAAYuC,EAAQjF,GAAIxC,KAAM6H,EAAQJ,EAAQjF,IAAKuB,IAMpE,GAAI2D,EAAU,MAAO1H,KACrB,KAAKwH,EAAQ,CACX,MAAOxH,KAAKgI,SAAU,CACpBjE,EAAU/D,KAAKgI,QACfhI,MAAKgI,SAAW,KAChBhI,MAAKkF,QAAQ,SAAUlF,KAAM+D,IAGjC/D,KAAKgI,SAAW,KAChBhI,MAAK2H,UAAY,KACjB,OAAO3H,OAKTuH,MAAO,SAASN,EAAMlD,GACpB,MAAO/D,MAAKyG,IAAIQ,MAAW,GAAGhI,EAAEgH,UAAWlC,GAAUwD,MAAO,SAI9DU,MAAO,SAASlE,GACd,GAAIlC,KACJ,KAAK,GAAIuF,KAAOpH,MAAKgC,WAAYH,EAAMuF,OAAY,EACnD,OAAOpH,MAAKyG,IAAI5E,EAAO5C,EAAEgH,UAAWlC,GAAUwD,MAAO,SAKvDW,WAAY,SAASjB,GACnB,GAAIA,GAAQ,KAAM,OAAQhI,EAAEqF,QAAQtE,KAAK0G,QACzC,OAAOzH,GAAEkI,IAAInH,KAAK0G,QAASO,IAS7BkB,kBAAmB,SAASC,GAC1B,IAAKA,EAAM,MAAOpI,MAAKkI,aAAejJ,EAAE8H,MAAM/G,KAAK0G,SAAW,KAC9D,IAAI2B,GAAMrI,KAAK2H,UAAY3H,KAAK4H,oBAAsB5H,KAAKgC,UAC3D,IAAI0E,KACJ,KAAK,GAAIO,KAAQmB,GAAM,CACrB,GAAIf,GAAMe,EAAKnB,EACf,IAAIhI,EAAE8I,QAAQM,EAAIpB,GAAOI,GAAM,QAC/BX,GAAQO,GAAQI,EAElB,MAAOpI,GAAE0F,KAAK+B,GAAWA,EAAU,OAKrC4B,SAAU,SAASrB,GACjB,GAAIA,GAAQ,OAASjH,KAAK4H,oBAAqB,MAAO,KACtD,OAAO5H,MAAK4H,oBAAoBX,IAKlCsB,mBAAoB,WAClB,MAAOtJ,GAAE8H,MAAM/G,KAAK4H,sBAKtBY,MAAO,SAASzE,GACdA,EAAU9E,EAAEgH,QAAQK,MAAO,MAAOvC,EAClC,IAAIpC,GAAQ3B,IACZ,IAAIyI,GAAU1E,EAAQ0E,OACtB1E,GAAQ0E,QAAU,SAASC,GACzB,GAAIC,GAAc5E,EAAQuC,MAAQ3E,EAAM2E,MAAMoC,EAAM3E,GAAW2E,CAC/D,KAAK/G,EAAM8E,IAAIkC,EAAa5E,GAAU,MAAO,MAC7C,IAAI0E,EAASA,EAAQ5H,KAAKkD,EAAQtD,QAASkB,EAAO+G,EAAM3E,EACxDpC,GAAMuD,QAAQ,OAAQvD,EAAO+G,EAAM3E,GAErC6E,GAAU5I,KAAM+D,EAChB,OAAO/D,MAAKgH,KAAK,OAAQhH,KAAM+D,IAMjC8E,KAAM,SAASzB,EAAKC,EAAKtD,GAEvB,GAAIlC,EACJ,IAAIuF,GAAO,YAAeA,KAAQ,SAAU,CAC1CvF,EAAQuF,CACRrD,GAAUsD,MACL,EACJxF,MAAYuF,GAAOC,EAGtBtD,EAAU9E,EAAEgH,QAAQ6C,SAAU,KAAMxC,MAAO,MAAOvC,EAClD,IAAIgF,GAAOhF,EAAQgF,IAKnB,IAAIlH,IAAUkH,EAAM,CAClB,IAAK/I,KAAKyG,IAAI5E,EAAOkC,GAAU,MAAO,WACjC,CACL,IAAK/D,KAAKsH,UAAUzF,EAAOkC,GAAU,MAAO,OAK9C,GAAIpC,GAAQ3B,IACZ,IAAIyI,GAAU1E,EAAQ0E,OACtB,IAAIzG,GAAahC,KAAKgC,UACtB+B,GAAQ0E,QAAU,SAASC,GAEzB/G,EAAMK,WAAaA,CACnB,IAAI2G,GAAc5E,EAAQuC,MAAQ3E,EAAM2E,MAAMoC,EAAM3E,GAAW2E,CAC/D,IAAIK,EAAMJ,EAAc1J,EAAEgH,UAAWpE,EAAO8G,EAC5C,IAAIA,IAAgBhH,EAAM8E,IAAIkC,EAAa5E,GAAU,MAAO,MAC5D,IAAI0E,EAASA,EAAQ5H,KAAKkD,EAAQtD,QAASkB,EAAO+G,EAAM3E,EACxDpC,GAAMuD,QAAQ,OAAQvD,EAAO+G,EAAM3E,GAErC6E,GAAU5I,KAAM+D,EAGhB,IAAIlC,GAASkH,EAAM/I,KAAKgC,WAAa/C,EAAEgH,UAAWjE,EAAYH,EAE9D,IAAIxB,GAASL,KAAKgJ,QAAU,SAAYjF,EAAQkF,MAAQ,QAAU,QAClE,IAAI5I,IAAW,UAAY0D,EAAQlC,MAAOkC,EAAQlC,MAAQA,CAC1D,IAAIqH,GAAMlJ,KAAKgH,KAAK3G,EAAQL,KAAM+D,EAGlC/D,MAAKgC,WAAaA,CAElB,OAAOkH,IAMTC,QAAS,SAASpF,GAChBA,EAAUA,EAAU9E,EAAE8H,MAAMhD,KAC5B,IAAIpC,GAAQ3B,IACZ,IAAIyI,GAAU1E,EAAQ0E,OACtB,IAAIM,GAAOhF,EAAQgF,IAEnB,IAAII,GAAU,WACZxH,EAAMyC,eACNzC,GAAMuD,QAAQ,UAAWvD,EAAOA,EAAM0E,WAAYtC,GAGpDA,GAAQ0E,QAAU,SAASC,GACzB,GAAIK,EAAMI,GACV,IAAIV,EAASA,EAAQ5H,KAAKkD,EAAQtD,QAASkB,EAAO+G,EAAM3E,EACxD,KAAKpC,EAAMqH,QAASrH,EAAMuD,QAAQ,OAAQvD,EAAO+G,EAAM3E,GAGzD,IAAImF,GAAM,KACV,IAAIlJ,KAAKgJ,QAAS,CAChB/J,EAAEmK,MAAMrF,EAAQ0E,aACX,CACLG,EAAU5I,KAAM+D,EAChBmF,GAAMlJ,KAAKgH,KAAK,SAAUhH,KAAM+D,GAElC,IAAKgF,EAAMI,GACX,OAAOD,IAMTG,IAAK,WACH,GAAIC,GACFrK,EAAEuH,OAAOxG,KAAM,YACff,EAAEuH,OAAOxG,KAAKqG,WAAY,QAC1BkD,GACF,IAAIvJ,KAAKgJ,QAAS,MAAOM,EACzB,IAAIhG,GAAKtD,KAAK4B,IAAI5B,KAAK6G,YACvB,OAAOyC,GAAKE,QAAQ,SAAU,OAASC,mBAAmBnG,IAK5DgD,MAAO,SAASoC,EAAM3E,GACpB,MAAO2E,IAIT3B,MAAO,WACL,MAAO,IAAI/G,MAAK0J,YAAY1J,KAAKgC,aAInCgH,MAAO,WACL,OAAQhJ,KAAKmH,IAAInH,KAAK6G,cAIxB8C,QAAS,SAAS5F,GAChB,MAAO/D,MAAKsH,aAAcrI,EAAEsH,UAAUuC,SAAU,MAAO/E,KAKzDuD,UAAW,SAASzF,EAAOkC,GACzB,IAAKA,EAAQ+E,WAAa9I,KAAK8I,SAAU,MAAO,KAChDjH,GAAQ5C,EAAEgH,UAAWjG,KAAKgC,WAAYH,EACtC,IAAI+H,GAAQ5J,KAAK4G,gBAAkB5G,KAAK8I,SAASjH,EAAOkC,IAAY,IACpE,KAAK6F,EAAO,MAAO,KACnB5J,MAAKkF,QAAQ,UAAWlF,KAAM4J,EAAO3K,EAAEgH,OAAOlC,GAAU6C,gBAAiBgD,IACzE,OAAO,SAOX,IAAIC,IAAiBnH,KAAM,EAAGoH,OAAQ,EAAGC,MAAO,EAAGC,OAAQ,EAAGC,KAAM,EAChEC,KAAM,EAAGC,MAAO,EAAG7F,QAAS,EAGhCrD,GAAqBiF,EAAO2D,EAAc,aAe1C,IAAIO,GAAahL,EAASgL,WAAa,SAASC,EAAQtG,GACtDA,IAAYA,KACZ,IAAIA,EAAQpC,MAAO3B,KAAK2B,MAAQoC,EAAQpC,KACxC,IAAIoC,EAAQuG,iBAAoB,GAAGtK,KAAKsK,WAAavG,EAAQuG,UAC7DtK,MAAKuK,QACLvK,MAAK2G,WAAW3F,MAAMhB,KAAMc,UAC5B,IAAIuJ,EAAQrK,KAAKwK,MAAMH,EAAQpL,EAAEgH,QAAQuB,OAAQ,MAAOzD,IAI1D,IAAI0G,IAAcC,IAAK,KAAMC,OAAQ,KAAMC,MAAO,KAClD,IAAIC,IAAcH,IAAK,KAAMC,OAAQ,MAGrC,IAAIG,GAAS,SAASC,EAAOC,EAAQC,GACnCA,EAAK9F,KAAK+F,IAAI/F,KAAKC,IAAI6F,EAAI,GAAIF,EAAM3K,OACrC,IAAI+K,GAAOvL,MAAMmL,EAAM3K,OAAS6K,EAChC,IAAI7K,GAAS4K,EAAO5K,MACpB,KAAK,GAAIoC,GAAI,EAAGA,EAAI2I,EAAK/K,OAAQoC,IAAK2I,EAAK3I,GAAKuI,EAAMvI,EAAIyI,EAC1D,KAAKzI,EAAI,EAAGA,EAAIpC,EAAQoC,IAAKuI,EAAMvI,EAAIyI,GAAMD,EAAOxI,EACpD,KAAKA,EAAI,EAAGA,EAAI2I,EAAK/K,OAAQoC,IAAKuI,EAAMvI,EAAIpC,EAAS6K,GAAME,EAAK3I,GAIlEvD,GAAEgH,OAAOmE,EAAWvK,UAAWoC,GAI7BN,MAAOuE,EAIPS,WAAY,aAIZG,OAAQ,SAAS/C,GACf,MAAO/D,MAAKgF,IAAI,SAASrD,GAAS,MAAOA,GAAMmF,OAAO/C,MAIxDiD,KAAM,WACJ,MAAO5H,GAAS4H,KAAKhG,MAAMhB,KAAMc,YAMnC4J,IAAK,SAASL,EAAQtG,GACpB,MAAO/D,MAAKyG,IAAI4D,EAAQpL,EAAEgH,QAAQ2E,MAAO,OAAQ7G,EAAS8G,KAI5DF,OAAQ,SAASN,EAAQtG,GACvBA,EAAU9E,EAAEgH,UAAWlC,EACvB,IAAIqH,IAAYnM,EAAEoM,QAAQhB,EAC1BA,GAASe,GAAYf,GAAUpL,EAAE8H,MAAMsD,EACvC,IAAIiB,GAAUtL,KAAKuL,cAAclB,EAAQtG,EACzC,KAAKA,EAAQyD,QAAU8D,EAAStL,KAAKkF,QAAQ,SAAUlF,KAAM+D,EAC7D,OAAOqH,GAAWE,EAAQ,GAAKA,GAOjC7E,IAAK,SAAS4D,EAAQtG,GACpB,GAAIsG,GAAU,KAAM,MAEpBtG,GAAU9E,EAAEsH,YAAaxC,EAAS0G,EAClC,IAAI1G,EAAQuC,QAAUtG,KAAKwB,SAAS6I,GAASA,EAASrK,KAAKsG,MAAM+D,EAAQtG,EAEzE,IAAIqH,IAAYnM,EAAEoM,QAAQhB,EAC1BA,GAASe,GAAYf,GAAUA,EAAO1K,OAEtC,IAAIsL,GAAKlH,EAAQkH,EACjB,IAAIA,GAAM,KAAMA,GAAMA,CACtB,IAAIA,EAAK,EAAGA,GAAMjL,KAAKI,OAAS,CAEhC,IAAIqG,KACJ,IAAI+E,KACJ,IAAIC,KACJ,IAAIC,KAEJ,IAAIhB,GAAM3G,EAAQ2G,GAClB,IAAIE,GAAQ7G,EAAQ6G,KACpB,IAAID,GAAS5G,EAAQ4G,MAErB,IAAIgB,GAAO,KACX,IAAIC,GAAW5L,KAAKsK,YAAeW,GAAM,MAASlH,EAAQ4H,OAAS,KACnE,IAAIE,GAAW5M,EAAEyC,SAAS1B,KAAKsK,YAActK,KAAKsK,WAAa,IAI/D,IAAI3I,EACJ,KAAK,GAAIa,GAAI,EAAGA,EAAI6H,EAAOjK,OAAQoC,IAAK,CACtCb,EAAQ0I,EAAO7H,EAIf,IAAIsJ,GAAW9L,KAAK4B,IAAID,EACxB,IAAImK,EAAU,CACZ,GAAIlB,GAASjJ,IAAUmK,EAAU,CAC/B,GAAIjK,GAAQ7B,KAAKwB,SAASG,GAASA,EAAMK,WAAaL,CACtD,IAAIoC,EAAQuC,MAAOzE,EAAQiK,EAASxF,MAAMzE,EAAOkC,EACjD+H,GAASrF,IAAI5E,EAAOkC,EACpB,IAAI6H,IAAaD,EAAMA,EAAOG,EAAS5D,WAAW2D,GAEpD,IAAKH,EAASI,EAAS3F,KAAM,CAC3BuF,EAASI,EAAS3F,KAAO,IACzBM,GAAIxC,KAAK6H,GAEXzB,EAAO7H,GAAKsJ,MAGP,IAAIpB,EAAK,CACd/I,EAAQ0I,EAAO7H,GAAKxC,KAAK+L,cAAcpK,EAAOoC,EAC9C,IAAIpC,EAAO,CACT6J,EAAMvH,KAAKtC,EACX3B,MAAKgM,cAAcrK,EAAOoC,EAC1B2H,GAAS/J,EAAMwE,KAAO,IACtBM,GAAIxC,KAAKtC,KAMf,GAAIgJ,EAAQ,CACV,IAAKnI,EAAI,EAAGA,EAAIxC,KAAKI,OAAQoC,IAAK,CAChCb,EAAQ3B,KAAKqK,OAAO7H,EACpB,KAAKkJ,EAAS/J,EAAMwE,KAAMsF,EAASxH,KAAKtC,GAE1C,GAAI8J,EAASrL,OAAQJ,KAAKuL,cAAcE,EAAU1H,GAIpD,GAAIkI,GAAe,KACnB,IAAIzC,IAAWoC,GAAYlB,GAAOC,CAClC,IAAIlE,EAAIrG,QAAUoJ,EAAS,CACzByC,EAAejM,KAAKI,QAAUqG,EAAIrG,QAAUnB,EAAEiN,KAAKlM,KAAKqK,OAAQ,SAAS1I,EAAOwK,GAC9E,MAAOxK,KAAU8E,EAAI0F,IAEvBnM,MAAKqK,OAAOjK,OAAS,CACrB0K,GAAO9K,KAAKqK,OAAQ5D,EAAK,EACzBzG,MAAKI,OAASJ,KAAKqK,OAAOjK,WACrB,IAAIoL,EAAMpL,OAAQ,CACvB,GAAIwL,EAAUD,EAAO,IACrBb,GAAO9K,KAAKqK,OAAQmB,EAAOP,GAAM,KAAOjL,KAAKI,OAAS6K,EACtDjL,MAAKI,OAASJ,KAAKqK,OAAOjK,OAI5B,GAAIuL,EAAM3L,KAAK2L,MAAMnE,OAAQ,MAG7B,KAAKzD,EAAQyD,OAAQ,CACnB,IAAKhF,EAAI,EAAGA,EAAIgJ,EAAMpL,OAAQoC,IAAK,CACjC,GAAIyI,GAAM,KAAMlH,EAAQoI,MAAQlB,EAAKzI,CACrCb,GAAQ6J,EAAMhJ,EACdb,GAAMuD,QAAQ,MAAOvD,EAAO3B,KAAM+D,GAEpC,GAAI4H,GAAQM,EAAcjM,KAAKkF,QAAQ,OAAQlF,KAAM+D,EACrD,IAAIyH,EAAMpL,QAAUqL,EAASrL,OAAQJ,KAAKkF,QAAQ,SAAUlF,KAAM+D,GAIpE,MAAOqH,GAAWf,EAAO,GAAKA,GAOhCG,MAAO,SAASH,EAAQtG,GACtBA,EAAUA,EAAU9E,EAAE8H,MAAMhD,KAC5B,KAAK,GAAIvB,GAAI,EAAGA,EAAIxC,KAAKqK,OAAOjK,OAAQoC,IAAK,CAC3CxC,KAAKoM,iBAAiBpM,KAAKqK,OAAO7H,GAAIuB,GAExCA,EAAQsI,eAAiBrM,KAAKqK,MAC9BrK,MAAKuK,QACLF,GAASrK,KAAK0K,IAAIL,EAAQpL,EAAEgH,QAAQuB,OAAQ,MAAOzD,GACnD,KAAKA,EAAQyD,OAAQxH,KAAKkF,QAAQ,QAASlF,KAAM+D,EACjD,OAAOsG,IAITpG,KAAM,SAAStC,EAAOoC,GACpB,MAAO/D,MAAK0K,IAAI/I,EAAO1C,EAAEgH,QAAQgF,GAAIjL,KAAKI,QAAS2D,KAIrDuI,IAAK,SAASvI,GACZ,GAAIpC,GAAQ3B,KAAKiL,GAAGjL,KAAKI,OAAS,EAClC,OAAOJ,MAAK2K,OAAOhJ,EAAOoC,IAI5BhD,QAAS,SAASY,EAAOoC,GACvB,MAAO/D,MAAK0K,IAAI/I,EAAO1C,EAAEgH,QAAQgF,GAAI,GAAIlH,KAI3CwI,MAAO,SAASxI,GACd,GAAIpC,GAAQ3B,KAAKiL,GAAG,EACpB,OAAOjL,MAAK2K,OAAOhJ,EAAOoC,IAI5BpE,MAAO,WACL,MAAOA,GAAMqB,MAAMhB,KAAKqK,OAAQvJ,YAIlCc,IAAK,SAASmB,GACZ,GAAIA,GAAO,KAAM,WAAY,EAC7B,IAAIO,GAAKtD,KAAKwM,QAAQxM,KAAKwB,SAASuB,GAAOA,EAAIf,WAAae,EAC5D,OAAO/C,MAAKyM,MAAM1J,IAAQ/C,KAAKyM,MAAMnJ,IAAOtD,KAAKyM,MAAM1J,EAAIoD,MAI7D8E,GAAI,SAASkB,GACX,GAAIA,EAAQ,EAAGA,GAASnM,KAAKI,MAC7B,OAAOJ,MAAKqK,OAAO8B,IAKrBO,MAAO,SAAS7K,EAAO8K,GACrB,MAAO3M,MAAK2M,EAAQ,OAAS,UAAU9K,IAKzC+K,UAAW,SAAS/K,GAClB,MAAO7B,MAAK0M,MAAM7K,EAAO,OAM3B8J,KAAM,SAAS5H,GACb,GAAIuG,GAAatK,KAAKsK,UACtB,KAAKA,EAAY,KAAM,IAAIuC,OAAM,yCACjC9I,KAAYA,KAEZ,IAAI3D,GAASkK,EAAWlK,MACxB,IAAInB,EAAEqC,WAAWgJ,GAAaA,EAAarL,EAAE6F,KAAKwF,EAAYtK,KAG9D,IAAII,IAAW,GAAKnB,EAAEyC,SAAS4I,GAAa,CAC1CtK,KAAKqK,OAASrK,KAAK8M,OAAOxC,OACrB,CACLtK,KAAKqK,OAAOsB,KAAKrB,GAEnB,IAAKvG,EAAQyD,OAAQxH,KAAKkF,QAAQ,OAAQlF,KAAM+D,EAChD,OAAO/D,OAIT+M,MAAO,SAAS9F,GACd,MAAOhI,GAAE+N,OAAOhN,KAAKqK,OAAQ,MAAOpD,IAMtCuB,MAAO,SAASzE,GACdA,EAAU9E,EAAEgH,QAAQK,MAAO,MAAOvC,EAClC,IAAI0E,GAAU1E,EAAQ0E,OACtB,IAAIpC,GAAarG,IACjB+D,GAAQ0E,QAAU,SAASC,GACzB,GAAIrI,GAAS0D,EAAQyG,MAAQ,QAAU,KACvCnE,GAAWhG,GAAQqI,EAAM3E,EACzB,IAAI0E,EAASA,EAAQ5H,KAAKkD,EAAQtD,QAAS4F,EAAYqC,EAAM3E,EAC7DsC,GAAWnB,QAAQ,OAAQmB,EAAYqC,EAAM3E,GAE/C6E,GAAU5I,KAAM+D,EAChB,OAAO/D,MAAKgH,KAAK,OAAQhH,KAAM+D,IAMjCkJ,OAAQ,SAAStL,EAAOoC,GACtBA,EAAUA,EAAU9E,EAAE8H,MAAMhD,KAC5B,IAAIgF,GAAOhF,EAAQgF,IACnBpH,GAAQ3B,KAAK+L,cAAcpK,EAAOoC,EAClC,KAAKpC,EAAO,MAAO,MACnB,KAAKoH,EAAM/I,KAAK0K,IAAI/I,EAAOoC,EAC3B,IAAIsC,GAAarG,IACjB,IAAIyI,GAAU1E,EAAQ0E,OACtB1E,GAAQ0E,QAAU,SAAS9G,EAAO+G,EAAMwE,GACtC,GAAInE,EAAM1C,EAAWqE,IAAI/I,EAAOuL,EAChC,IAAIzE,EAASA,EAAQ5H,KAAKqM,EAAazM,QAASkB,EAAO+G,EAAMwE,GAE/DvL,GAAMkH,KAAK,KAAM9E,EACjB,OAAOpC,IAKT2E,MAAO,SAASoC,EAAM3E,GACpB,MAAO2E,IAIT3B,MAAO,WACL,MAAO,IAAI/G,MAAK0J,YAAY1J,KAAKqK,QAC/B1I,MAAO3B,KAAK2B,MACZ2I,WAAYtK,KAAKsK,cAKrBkC,QAAS,SAAU3K,GACjB,MAAOA,GAAM7B,KAAK2B,MAAM9B,UAAUgH,aAAe,OAKnD0D,OAAQ,WACNvK,KAAKI,OAAS,CACdJ,MAAKqK,SACLrK,MAAKyM,UAKPV,cAAe,SAASlK,EAAOkC,GAC7B,GAAI/D,KAAKwB,SAASK,GAAQ,CACxB,IAAKA,EAAMwE,WAAYxE,EAAMwE,WAAarG,IAC1C,OAAO6B,GAETkC,EAAUA,EAAU9E,EAAE8H,MAAMhD,KAC5BA,GAAQsC,WAAarG,IACrB,IAAI2B,GAAQ,GAAI3B,MAAK2B,MAAME,EAAOkC,EAClC,KAAKpC,EAAMiF,gBAAiB,MAAOjF,EACnC3B,MAAKkF,QAAQ,UAAWlF,KAAM2B,EAAMiF,gBAAiB7C,EACrD,OAAO,QAITwH,cAAe,SAASlB,EAAQtG,GAC9B,GAAIuH,KACJ,KAAK,GAAI9I,GAAI,EAAGA,EAAI6H,EAAOjK,OAAQoC,IAAK,CACtC,GAAIb,GAAQ3B,KAAK4B,IAAIyI,EAAO7H,GAC5B,KAAKb,EAAO,QAEZ,IAAIwK,GAAQnM,KAAKmN,QAAQxL,EACzB3B,MAAKqK,OAAOS,OAAOqB,EAAO,EAC1BnM,MAAKI,QAEL,KAAK2D,EAAQyD,OAAQ,CACnBzD,EAAQoI,MAAQA,CAChBxK,GAAMuD,QAAQ,SAAUvD,EAAO3B,KAAM+D,GAGvCuH,EAAQrH,KAAKtC,EACb3B,MAAKoM,iBAAiBzK,EAAOoC,GAE/B,MAAOuH,GAAQlL,OAASkL,EAAU,OAKpC9J,SAAU,SAAUG,GAClB,MAAOA,aAAiBuE,IAI1B8F,cAAe,SAASrK,EAAOoC,GAC7B/D,KAAKyM,MAAM9K,EAAMwE,KAAOxE,CACxB,IAAI2B,GAAKtD,KAAKwM,QAAQ7K,EAAMK,WAC5B,IAAIsB,GAAM,KAAMtD,KAAKyM,MAAMnJ,GAAM3B,CACjCA,GAAMkB,GAAG,MAAO7C,KAAKoN,cAAepN,OAItCoM,iBAAkB,SAASzK,EAAOoC,SACzB/D,MAAKyM,MAAM9K,EAAMwE,IACxB,IAAI7C,GAAKtD,KAAKwM,QAAQ7K,EAAMK,WAC5B,IAAIsB,GAAM,WAAatD,MAAKyM,MAAMnJ,EAClC,IAAItD,OAAS2B,EAAM0E,iBAAmB1E,GAAM0E,UAC5C1E,GAAMuC,IAAI,MAAOlE,KAAKoN,cAAepN,OAOvCoN,cAAe,SAASC,EAAO1L,EAAO0E,EAAYtC,GAChD,IAAKsJ,IAAU,OAASA,IAAU,WAAahH,IAAerG,KAAM,MACpE,IAAIqN,IAAU,UAAWrN,KAAK2K,OAAOhJ,EAAOoC,EAC5C,IAAIsJ,IAAU,SAAU,CACtB,GAAIC,GAAStN,KAAKwM,QAAQ7K,EAAM4G,qBAChC,IAAIjF,GAAKtD,KAAKwM,QAAQ7K,EAAMK,WAC5B,IAAIsL,IAAWhK,EAAI,CACjB,GAAIgK,GAAU,WAAatN,MAAKyM,MAAMa,EACtC,IAAIhK,GAAM,KAAMtD,KAAKyM,MAAMnJ,GAAM3B,GAGrC3B,KAAKkF,QAAQlE,MAAMhB,KAAMc,aAQ7B,IAAIyM,IAAsBC,QAAS,EAAGpM,KAAM,EAAG4D,IAAK,EAAGyI,QAAS,EAAGC,OAAQ,EACvEC,MAAO,EAAGC,OAAQ,EAAGC,YAAa,EAAGC,MAAO,EAAGC,KAAM,EAAGC,OAAQ,EAAGC,OAAQ,EAC3EC,OAAQ,EAAGC,OAAQ,EAAGC,MAAO,EAAG5I,IAAK,EAAG0G,KAAM,EAAGmC,IAAK,EAAGC,QAAS,EAAGC,SAAU,EAC/EC,SAAU,EAAGxB,OAAQ,EAAG5H,IAAK,EAAG8F,IAAK,EAAGuD,QAAS,EAAG9J,KAAM,EAAGgI,MAAO,EACpE+B,KAAM,EAAGC,KAAM,EAAGC,QAAS,EAAGC,KAAM,EAAG1D,KAAM,EAAG2D,KAAM,EAAGC,KAAM,EAC/DC,QAAS,EAAGC,WAAY,EAAG9B,QAAS,EAAG+B,QAAS,EAAGC,YAAa,EAChE7K,QAAS,EAAG6F,MAAO,EAAGiF,OAAQ,EAAGC,UAAW,EAAGC,QAAS,EAAGC,QAAS,EACpEzC,OAAQ,EAAG0C,QAAS,EAGxBvO,GAAqBmJ,EAAYmD,EAAmB,SAepD,IAAIkC,GAAOrQ,EAASqQ,KAAO,SAAS1L,GAClC/D,KAAKmG,IAAMlH,EAAEwE,SAAS,OACtBxE,GAAEgH,OAAOjG,KAAMf,EAAEgL,KAAKlG,EAAS2L,GAC/B1P,MAAK2P,gBACL3P,MAAK2G,WAAW3F,MAAMhB,KAAMc,WAI9B,IAAI8O,GAAwB,gBAG5B,IAAIF,IAAe,QAAS,aAAc,KAAM,KAAM,aAAc,YAAa,UAAW,SAG5FzQ,GAAEgH,OAAOwJ,EAAK5P,UAAWoC,GAGvB4N,QAAS,MAIT3Q,EAAG,SAAS4Q,GACV,MAAO9P,MAAK+P,IAAIhC,KAAK+B,IAKvBnJ,WAAY,aAKZqJ,OAAQ,WACN,MAAOhQ,OAKT2K,OAAQ,WACN3K,KAAKiQ,gBACLjQ,MAAKoE,eACL,OAAOpE,OAMTiQ,eAAgB,WACdjQ,KAAK+P,IAAIpF,UAKXuF,WAAY,SAASC,GACnBnQ,KAAKoQ,kBACLpQ,MAAKqQ,YAAYF,EACjBnQ,MAAKsQ,gBACL,OAAOtQ,OAQTqQ,YAAa,SAASE,GACpBvQ,KAAK+P,IAAMQ,YAAcnR,GAASF,EAAIqR,EAAKnR,EAASF,EAAEqR,EACtDvQ,MAAKuQ,GAAKvQ,KAAK+P,IAAI,IAgBrBO,eAAgB,SAASlO,GACvBA,IAAWA,EAASnD,EAAEuH,OAAOxG,KAAM,UACnC,KAAKoC,EAAQ,MAAOpC,KACpBA,MAAKoQ,kBACL,KAAK,GAAIhJ,KAAOhF,GAAQ,CACtB,GAAI/B,GAAS+B,EAAOgF,EACpB,KAAKnI,EAAEqC,WAAWjB,GAASA,EAASL,KAAKK,EACzC,KAAKA,EAAQ,QACb,IAAImQ,GAAQpJ,EAAIoJ,MAAMZ,EACtB5P,MAAKyQ,SAASD,EAAM,GAAIA,EAAM,GAAIvR,EAAE6F,KAAKzE,EAAQL,OAEnD,MAAOA,OAMTyQ,SAAU,SAASC,EAAWZ,EAAUa,GACtC3Q,KAAK+P,IAAIlN,GAAG6N,EAAY,kBAAoB1Q,KAAKmG,IAAK2J,EAAUa,EAChE,OAAO3Q,OAMToQ,iBAAkB,WAChB,GAAIpQ,KAAK+P,IAAK/P,KAAK+P,IAAI7L,IAAI,kBAAoBlE,KAAKmG,IACpD,OAAOnG,OAKT4Q,WAAY,SAASF,EAAWZ,EAAUa,GACxC3Q,KAAK+P,IAAI7L,IAAIwM,EAAY,kBAAoB1Q,KAAKmG,IAAK2J,EAAUa,EACjE,OAAO3Q,OAKT6Q,eAAgB,SAAShB,GACvB,MAAOiB,UAASC,cAAclB,IAOhCF,eAAgB,WACd,IAAK3P,KAAKuQ,GAAI,CACZ,GAAI1O,GAAQ5C,EAAEgH,UAAWhH,EAAEuH,OAAOxG,KAAM,cACxC,IAAIA,KAAKsD,GAAIzB,EAAMyB,GAAKrE,EAAEuH,OAAOxG,KAAM,KACvC,IAAIA,KAAKgR,UAAWnP,EAAM,SAAW5C,EAAEuH,OAAOxG,KAAM,YACpDA,MAAKkQ,WAAWlQ,KAAK6Q,eAAe5R,EAAEuH,OAAOxG,KAAM,YACnDA,MAAKiR,eAAepP,OACf,CACL7B,KAAKkQ,WAAWjR,EAAEuH,OAAOxG,KAAM,SAMnCiR,eAAgB,SAASjP,GACvBhC,KAAK+P,IAAI9I,KAAKjF,KAuBlB5C,GAAS4H,KAAO,SAAS3G,EAAQsB,EAAOoC,GACtC,GAAImN,GAAOC,EAAU9Q,EAGrBpB,GAAEsH,SAASxC,IAAYA,OACrB9D,YAAab,EAASa,YACtBC,YAAad,EAASc,aAIxB,IAAIkR,IAAUF,KAAMA,EAAMG,SAAU,OAGpC,KAAKtN,EAAQsF,IAAK,CAChB+H,EAAO/H,IAAMpK,EAAEuH,OAAO7E,EAAO,QAAU4H,IAIzC,GAAIxF,EAAQuN,MAAQ,MAAQ3P,IAAUtB,IAAW,UAAYA,IAAW,UAAYA,IAAW,SAAU,CACvG+Q,EAAOG,YAAc,kBACrBH,GAAOE,KAAOE,KAAKC,UAAU1N,EAAQlC,OAASF,EAAMmF,OAAO/C,IAI7D,GAAIA,EAAQ7D,YAAa,CACvBkR,EAAOG,YAAc,mCACrBH,GAAOE,KAAOF,EAAOE,MAAQ3P,MAAOyP,EAAOE,SAK7C,GAAIvN,EAAQ9D,cAAgBiR,IAAS,OAASA,IAAS,UAAYA,IAAS,SAAU,CACpFE,EAAOF,KAAO,MACd,IAAInN,EAAQ7D,YAAakR,EAAOE,KAAKI,QAAUR,CAC/C,IAAIS,GAAa5N,EAAQ4N,UACzB5N,GAAQ4N,WAAa,SAASzI,GAC5BA,EAAI0I,iBAAiB,yBAA0BV,EAC/C,IAAIS,EAAY,MAAOA,GAAW3Q,MAAMhB,KAAMc,YAKlD,GAAIsQ,EAAOF,OAAS,QAAUnN,EAAQ7D,YAAa,CACjDkR,EAAOS,YAAc,MAIvB,GAAIjI,GAAQ7F,EAAQ6F,KACpB7F,GAAQ6F,MAAQ,SAASV,EAAK4I,EAAYC,GACxChO,EAAQ+N,WAAaA,CACrB/N,GAAQgO,YAAcA,CACtB,IAAInI,EAAOA,EAAM/I,KAAKkD,EAAQtD,QAASyI,EAAK4I,EAAYC,GAI1D,IAAI7I,GAAMnF,EAAQmF,IAAM9J,EAAS4S,KAAK/S,EAAEgH,OAAOmL,EAAQrN,GACvDpC,GAAMuD,QAAQ,UAAWvD,EAAOuH,EAAKnF,EACrC,OAAOmF,GAIT,IAAIiI,IACFlE,OAAU,OACVgF,OAAU,MACVhJ,MAAU,QACViJ,SAAU,SACVC,KAAU,MAKZ/S,GAAS4S,KAAO,WACd,MAAO5S,GAASF,EAAE8S,KAAKhR,MAAM5B,EAASF,EAAG4B,WAQ3C,IAAIsR,GAAShT,EAASgT,OAAS,SAASrO,GACtCA,IAAYA,KACZ,IAAIA,EAAQsO,OAAQrS,KAAKqS,OAAStO,EAAQsO,MAC1CrS,MAAKsS,aACLtS,MAAK2G,WAAW3F,MAAMhB,KAAMc,WAK9B,IAAIyR,GAAgB,YACpB,IAAIC,GAAgB,cACpB,IAAIC,GAAgB,QACpB,IAAIC,GAAgB,0BAGpBzT,GAAEgH,OAAOmM,EAAOvS,UAAWoC,GAIzB0E,WAAY,aAQZgM,MAAO,SAASA,EAAOtQ,EAAMC,GAC3B,IAAKrD,EAAE2T,SAASD,GAAQA,EAAQ3S,KAAK6S,eAAeF,EACpD,IAAI1T,EAAEqC,WAAWe,GAAO,CACtBC,EAAWD,CACXA,GAAO,GAET,IAAKC,EAAUA,EAAWtC,KAAKqC,EAC/B,IAAIyQ,GAAS9S,IACbZ,GAAS2T,QAAQJ,MAAMA,EAAO,SAASK,GACrC,GAAIpS,GAAOkS,EAAOG,mBAAmBN,EAAOK,EAC5C,IAAIF,EAAOI,QAAQ5Q,EAAU1B,EAAMyB,KAAU,MAAO,CAClDyQ,EAAO5N,QAAQlE,MAAM8R,GAAS,SAAWzQ,GAAMqD,OAAO9E,GACtDkS,GAAO5N,QAAQ,QAAS7C,EAAMzB,EAC9BxB,GAAS2T,QAAQ7N,QAAQ,QAAS4N,EAAQzQ,EAAMzB,KAGpD,OAAOZ,OAKTkT,QAAS,SAAS5Q,EAAU1B,EAAMyB,GAChC,GAAIC,EAAUA,EAAStB,MAAMhB,KAAMY,IAIrCuS,SAAU,SAASH,EAAUjP,GAC3B3E,EAAS2T,QAAQI,SAASH,EAAUjP,EACpC,OAAO/D,OAMTsS,YAAa,WACX,IAAKtS,KAAKqS,OAAQ,MAClBrS,MAAKqS,OAASpT,EAAEuH,OAAOxG,KAAM,SAC7B,IAAI2S,GAAON,EAASpT,EAAEyD,KAAK1C,KAAKqS,OAChC,QAAQM,EAAQN,EAAO/F,QAAU,KAAM,CACrCtM,KAAK2S,MAAMA,EAAO3S,KAAKqS,OAAOM,MAMlCE,eAAgB,SAASF,GACvBA,EAAQA,EAAMnJ,QAAQkJ,EAAc,QACtBlJ,QAAQ+I,EAAe,WACvB/I,QAAQgJ,EAAY,SAAShC,EAAO4C,GACnC,MAAOA,GAAW5C,EAAQ,aAE3BhH,QAAQiJ,EAAY,WAClC,OAAO,IAAIY,QAAO,IAAMV,EAAQ,yBAMlCM,mBAAoB,SAASN,EAAOK,GAClC,GAAI5B,GAASuB,EAAMW,KAAKN,GAAUrT,MAAM,EACxC,OAAOV,GAAE+F,IAAIoM,EAAQ,SAASmC,EAAO/Q,GAEnC,GAAIA,IAAM4O,EAAOhR,OAAS,EAAG,MAAOmT,IAAS,IAC7C,OAAOA,GAAQC,mBAAmBD,GAAS,SAcjD,IAAIE,GAAUrU,EAASqU,QAAU,WAC/BzT,KAAKgE,WACLhE,MAAK0T,SAAWzU,EAAE6F,KAAK9E,KAAK0T,SAAU1T,KAGtC,UAAW2T,UAAW,YAAa,CACjC3T,KAAK4T,SAAWD,OAAOC,QACvB5T,MAAK+S,QAAUY,OAAOZ,SAK1B,IAAIc,GAAgB,cAGpB,IAAIC,GAAe,YAGnB,IAAIC,GAAe,MAGnBN,GAAQO,QAAU,KAGlB/U,GAAEgH,OAAOwN,EAAQ5T,UAAWoC,GAI1BgS,SAAU,GAGVC,OAAQ,WACN,GAAIC,GAAOnU,KAAK4T,SAASQ,SAAS5K,QAAQ,SAAU,MACpD,OAAO2K,KAASnU,KAAKpB,OAASoB,KAAKqU,aAIrCC,UAAW,WACT,GAAIH,GAAOnU,KAAKuU,eAAevU,KAAK4T,SAASQ,SAC7C,IAAIxV,GAAOuV,EAAKxU,MAAM,EAAGK,KAAKpB,KAAKwB,OAAS,GAAK,GACjD,OAAOxB,KAASoB,KAAKpB,MAMvB2V,eAAgB,SAASvB,GACvB,MAAOwB,WAAUxB,EAASxJ,QAAQ,OAAQ,WAK5C6K,UAAW,WACT,GAAI7D,GAAQxQ,KAAK4T,SAASa,KAAKjL,QAAQ,MAAO,IAAIgH,MAAM,OACxD,OAAOA,GAAQA,EAAM,GAAK,IAK5BkE,QAAS,SAASf,GAChB,GAAInD,IAASmD,GAAU3T,MAAM4T,SAASa,KAAKjE,MAAM,SACjD,OAAOA,GAAQA,EAAM,GAAK,IAI5BmE,QAAS,WACP,GAAIR,GAAOnU,KAAKuU,eACdvU,KAAK4T,SAASQ,SAAWpU,KAAKqU,aAC9B1U,MAAMK,KAAKpB,KAAKwB,OAAS,EAC3B,OAAO+T,GAAKS,OAAO,KAAO,IAAMT,EAAKxU,MAAM,GAAKwU,GAIlDU,YAAa,SAAS7B,GACpB,GAAIA,GAAY,KAAM,CACpB,GAAIhT,KAAK8U,gBAAkB9U,KAAK+U,iBAAkB,CAChD/B,EAAWhT,KAAK2U,cACX,CACL3B,EAAWhT,KAAK0U,WAGpB,MAAO1B,GAASxJ,QAAQqK,EAAe,KAKzCmB,MAAO,SAASjR,GACd,GAAI0P,EAAQO,QAAS,KAAM,IAAInH,OAAM,4CACrC4G,GAAQO,QAAU,IAIlBhU,MAAK+D,QAAmB9E,EAAEgH,QAAQrH,KAAM,KAAMoB,KAAK+D,QAASA,EAC5D/D,MAAKpB,KAAmBoB,KAAK+D,QAAQnF,IACrCoB,MAAK+U,iBAAmB/U,KAAK+D,QAAQkR,aAAe,KACpDjV,MAAKkV,eAAmB,gBAAkBvB,UAAW7C,SAASqE,mBAAsB,IAAKrE,SAASqE,aAAe,EACjHnV,MAAKoV,eAAmBpV,KAAK+U,kBAAoB/U,KAAKkV,cACtDlV,MAAKqV,kBAAqBrV,KAAK+D,QAAQuR,SACvCtV,MAAKuV,iBAAsBvV,KAAK+S,SAAW/S,KAAK+S,QAAQuC,UACxDtV,MAAK8U,cAAmB9U,KAAKqV,iBAAmBrV,KAAKuV,aACrDvV,MAAKgT,SAAmBhT,KAAK6U,aAG7B7U,MAAKpB,MAAQ,IAAMoB,KAAKpB,KAAO,KAAK4K,QAAQsK,EAAc,IAI1D,IAAI9T,KAAK+U,kBAAoB/U,KAAKqV,gBAAiB,CAIjD,IAAKrV,KAAKuV,gBAAkBvV,KAAKkU,SAAU,CACzC,GAAItV,GAAOoB,KAAKpB,KAAKe,MAAM,GAAI,IAAM,GACrCK,MAAK4T,SAASpK,QAAQ5K,EAAO,IAAMoB,KAAK2U,UAExC,OAAO,UAIF,IAAI3U,KAAKuV,eAAiBvV,KAAKkU,SAAU,CAC9ClU,KAAKmT,SAASnT,KAAK0U,WAAYlL,QAAS,QAQ5C,IAAKxJ,KAAKkV,gBAAkBlV,KAAK+U,mBAAqB/U,KAAK8U,cAAe,CACxE9U,KAAKwV,OAAS1E,SAASC,cAAc,SACrC/Q,MAAKwV,OAAOC,IAAM,cAClBzV,MAAKwV,OAAOE,MAAMC,QAAU,MAC5B3V,MAAKwV,OAAOI,UAAY,CACxB,IAAIC,GAAO/E,SAAS+E,IAEpB,IAAIC,GAAUD,EAAKE,aAAa/V,KAAKwV,OAAQK,EAAKG,YAAYC,aAC9DH,GAAQhF,SAASoF,MACjBJ,GAAQhF,SAASqF,OACjBL,GAAQlC,SAASwC,KAAO,IAAMpW,KAAKgT,SAIrC,GAAIqD,GAAmB1C,OAAO0C,kBAAoB,SAAU3F,EAAWC,GACrE,MAAO2F,aAAY,KAAO5F,EAAWC,GAKvC,IAAI3Q,KAAK8U,cAAe,CACtBuB,EAAiB,WAAYrW,KAAK0T,SAAU,WACvC,IAAI1T,KAAKoV,iBAAmBpV,KAAKwV,OAAQ,CAC9Ca,EAAiB,aAAcrW,KAAK0T,SAAU,WACzC,IAAI1T,KAAK+U,iBAAkB,CAChC/U,KAAKuW,kBAAoBC,YAAYxW,KAAK0T,SAAU1T,KAAKiU,UAG3D,IAAKjU,KAAK+D,QAAQyD,OAAQ,MAAOxH,MAAKyW,WAKxCC,KAAM,WAEJ,GAAIC,GAAsBhD,OAAOgD,qBAAuB,SAAUjG,EAAWC,GAC3E,MAAOiG,aAAY,KAAOlG,EAAWC,GAIvC,IAAI3Q,KAAK8U,cAAe,CACtB6B,EAAoB,WAAY3W,KAAK0T,SAAU,WAC1C,IAAI1T,KAAKoV,iBAAmBpV,KAAKwV,OAAQ,CAC9CmB,EAAoB,aAAc3W,KAAK0T,SAAU,OAInD,GAAI1T,KAAKwV,OAAQ,CACf1E,SAAS+E,KAAKgB,YAAY7W,KAAKwV,OAC/BxV,MAAKwV,OAAS,KAIhB,GAAIxV,KAAKuW,kBAAmBO,cAAc9W,KAAKuW,kBAC/C9C,GAAQO,QAAU,OAKpBrB,MAAO,SAASA,EAAOrQ,GACrBtC,KAAKgE,SAASjD,SAAS4R,MAAOA,EAAOrQ,SAAUA,KAKjDoR,SAAU,SAASpU,GACjB,GAAIuI,GAAU7H,KAAK6U,aAInB,IAAIhN,IAAY7H,KAAKgT,UAAYhT,KAAKwV,OAAQ,CAC5C3N,EAAU7H,KAAK0U,QAAQ1U,KAAKwV,OAAOS,eAGrC,GAAIpO,IAAY7H,KAAKgT,SAAU,MAAO,MACtC,IAAIhT,KAAKwV,OAAQxV,KAAKmT,SAAStL,EAC/B7H,MAAKyW,WAMPA,QAAS,SAASzD,GAEhB,IAAKhT,KAAKsU,YAAa,MAAO,MAC9BtB,GAAWhT,KAAKgT,SAAWhT,KAAK6U,YAAY7B,EAC5C,OAAO/T,GAAEiN,KAAKlM,KAAKgE,SAAU,SAASS,GACpC,GAAIA,EAAQkO,MAAMhQ,KAAKqQ,GAAW,CAChCvO,EAAQnC,SAAS0Q,EACjB,OAAO,UAYbG,SAAU,SAASH,EAAUjP,GAC3B,IAAK0P,EAAQO,QAAS,MAAO,MAC7B,KAAKjQ,GAAWA,IAAY,KAAMA,GAAWmB,UAAWnB,EAGxDiP,GAAWhT,KAAK6U,YAAY7B,GAAY,GAGxC,IAAIpU,GAAOoB,KAAKpB,IAChB,IAAIoU,IAAa,IAAMA,EAAS4B,OAAO,KAAO,IAAK,CACjDhW,EAAOA,EAAKe,MAAM,GAAI,IAAM,IAE9B,GAAI0J,GAAMzK,EAAOoU,CAGjBA,GAAWhT,KAAKuU,eAAevB,EAASxJ,QAAQuK,EAAc,IAE9D,IAAI/T,KAAKgT,WAAaA,EAAU,MAChChT,MAAKgT,SAAWA,CAGhB,IAAIhT,KAAK8U,cAAe,CACtB9U,KAAK+S,QAAQhP,EAAQyF,QAAU,eAAiB,gBAAiBsH,SAASiG,MAAO1N,OAI5E,IAAIrJ,KAAK+U,iBAAkB,CAChC/U,KAAKgX,YAAYhX,KAAK4T,SAAUZ,EAAUjP,EAAQyF,QAClD,IAAIxJ,KAAKwV,QAAWxC,IAAahT,KAAK0U,QAAQ1U,KAAKwV,OAAOS,eAAiB,CACzE,GAAIH,GAAU9V,KAAKwV,OAAOS,aAK1B,KAAKlS,EAAQyF,QAAS,CACpBsM,EAAQhF,SAASoF,MACjBJ,GAAQhF,SAASqF,QAGnBnW,KAAKgX,YAAYlB,EAAQlC,SAAUZ,EAAUjP,EAAQyF,cAKlD,CACL,MAAOxJ,MAAK4T,SAASqD,OAAO5N,GAE9B,GAAItF,EAAQmB,QAAS,MAAOlF,MAAKyW,QAAQzD,IAK3CgE,YAAa,SAASpD,EAAUZ,EAAUxJ,GACxC,GAAIA,EAAS,CACX,GAAIiL,GAAOb,EAASa,KAAKjL,QAAQ,qBAAsB,GACvDoK,GAASpK,QAAQiL,EAAO,IAAMzB,OACzB,CAELY,EAASwC,KAAO,IAAMpD,KAO5B5T,GAAS2T,QAAU,GAAIU,EAQvB,IAAIxN,GAAS,SAASiR,EAAYC,GAChC,GAAIC,GAASpX,IACb,IAAIqX,EAKJ,IAAIH,GAAcjY,EAAEkI,IAAI+P,EAAY,eAAgB,CAClDG,EAAQH,EAAWxN,gBACd,CACL2N,EAAQ,WAAY,MAAOD,GAAOpW,MAAMhB,KAAMc,YAIhD7B,EAAEgH,OAAOoR,EAAOD,EAAQD,EAIxB,IAAIG,GAAY,WAAYtX,KAAK0J,YAAc2N,EAC/CC,GAAUzX,UAAYuX,EAAOvX,SAC7BwX,GAAMxX,UAAY,GAAIyX,EAItB,IAAIJ,EAAYjY,EAAEgH,OAAOoR,EAAMxX,UAAWqX,EAI1CG,GAAME,UAAYH,EAAOvX,SAEzB,OAAOwX,GAITnR,GAAMD,OAASmE,EAAWnE,OAASmM,EAAOnM,OAASwJ,EAAKxJ,OAASwN,EAAQxN,OAASA,CAGlF,IAAIsD,GAAW,WACb,KAAM,IAAIsD,OAAM,kDAIlB,IAAIjE,GAAY,SAASjH,EAAOoC,GAC9B,GAAI6F,GAAQ7F,EAAQ6F,KACpB7F,GAAQ6F,MAAQ,SAASlB,GACvB,GAAIkB,EAAOA,EAAM/I,KAAKkD,EAAQtD,QAASkB,EAAO+G,EAAM3E,EACpDpC,GAAMuD,QAAQ,QAASvD,EAAO+G,EAAM3E,IAIxC,OAAO3E"}
\ No newline at end of file
// Backbone.js 1.2.3
// (c) 2010-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Backbone may be freely distributed under the MIT license.
// For all details and documentation:
// http://backbonejs.org
(function(factory) {
// Establish the root object, `window` (`self`) in the browser, or `global` on the server.
// We use `self` instead of `window` for `WebWorker` support.
var root = (typeof self == 'object' && self.self == self && self) ||
(typeof global == 'object' && global.global == global && global);
// Set up Backbone appropriately for the environment. Start with AMD.
if (typeof define === 'function' && define.amd) {
define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
// Export global even in AMD case in case this script is loaded with
// others that may still expect a global Backbone.
root.Backbone = factory(root, exports, _, $);
});
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
} else if (typeof exports !== 'undefined') {
var _ = require('underscore'), $;
try { $ = require('jquery'); } catch(e) {}
factory(root, exports, _, $);
// Finally, as a browser global.
} else {
root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
}
}(function(root, Backbone, _, $) {
// Initial Setup
// -------------
// Save the previous value of the `Backbone` variable, so that it can be
// restored later on, if `noConflict` is used.
var previousBackbone = root.Backbone;
// Create a local reference to a common array method we'll want to use later.
var slice = Array.prototype.slice;
// Current version of the library. Keep in sync with `package.json`.
Backbone.VERSION = '1.2.3';
// For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
// the `$` variable.
Backbone.$ = $;
// Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
// to its previous owner. Returns a reference to this Backbone object.
Backbone.noConflict = function() {
root.Backbone = previousBackbone;
return this;
};
// Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
// will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
// set a `X-Http-Method-Override` header.
Backbone.emulateHTTP = false;
// Turn on `emulateJSON` to support legacy servers that can't deal with direct
// `application/json` requests ... this will encode the body as
// `application/x-www-form-urlencoded` instead and will send the model in a
// form param named `model`.
Backbone.emulateJSON = false;
// Proxy Backbone class methods to Underscore functions, wrapping the model's
// `attributes` object or collection's `models` array behind the scenes.
//
// collection.filter(function(model) { return model.get('age') > 10 });
// collection.each(this.addView);
//
// `Function#apply` can be slow so we use the method's arg count, if we know it.
var addMethod = function(length, method, attribute) {
switch (length) {
case 1: return function() {
return _[method](this[attribute]);
};
case 2: return function(value) {
return _[method](this[attribute], value);
};
case 3: return function(iteratee, context) {
return _[method](this[attribute], cb(iteratee, this), context);
};
case 4: return function(iteratee, defaultVal, context) {
return _[method](this[attribute], cb(iteratee, this), defaultVal, context);
};
default: return function() {
var args = slice.call(arguments);
args.unshift(this[attribute]);
return _[method].apply(_, args);
};
}
};
var addUnderscoreMethods = function(Class, methods, attribute) {
_.each(methods, function(length, method) {
if (_[method]) Class.prototype[method] = addMethod(length, method, attribute);
});
};
// Support `collection.sortBy('attr')` and `collection.findWhere({id: 1})`.
var cb = function(iteratee, instance) {
if (_.isFunction(iteratee)) return iteratee;
if (_.isObject(iteratee) && !instance._isModel(iteratee)) return modelMatcher(iteratee);
if (_.isString(iteratee)) return function(model) { return model.get(iteratee); };
return iteratee;
};
var modelMatcher = function(attrs) {
var matcher = _.matches(attrs);
return function(model) {
return matcher(model.attributes);
};
};
// Backbone.Events
// ---------------
// A module that can be mixed in to *any object* in order to provide it with
// a custom event channel. You may bind a callback to an event with `on` or
// remove with `off`; `trigger`-ing an event fires all callbacks in
// succession.
//
// var object = {};
// _.extend(object, Backbone.Events);
// object.on('expand', function(){ alert('expanded'); });
// object.trigger('expand');
//
var Events = Backbone.Events = {};
// Regular expression used to split event strings.
var eventSplitter = /\s+/;
// Iterates over the standard `event, callback` (as well as the fancy multiple
// space-separated events `"change blur", callback` and jQuery-style event
// maps `{event: callback}`).
var eventsApi = function(iteratee, events, name, callback, opts) {
var i = 0, names;
if (name && typeof name === 'object') {
// Handle event maps.
if (callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback;
for (names = _.keys(name); i < names.length ; i++) {
events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
}
} else if (name && eventSplitter.test(name)) {
// Handle space separated event names by delegating them individually.
for (names = name.split(eventSplitter); i < names.length; i++) {
events = iteratee(events, names[i], callback, opts);
}
} else {
// Finally, standard events.
events = iteratee(events, name, callback, opts);
}
return events;
};
// Bind an event to a `callback` function. Passing `"all"` will bind
// the callback to all events fired.
Events.on = function(name, callback, context) {
return internalOn(this, name, callback, context);
};
// Guard the `listening` argument from the public API.
var internalOn = function(obj, name, callback, context, listening) {
obj._events = eventsApi(onApi, obj._events || {}, name, callback, {
context: context,
ctx: obj,
listening: listening
});
if (listening) {
var listeners = obj._listeners || (obj._listeners = {});
listeners[listening.id] = listening;
}
return obj;
};
// Inversion-of-control versions of `on`. Tell *this* object to listen to
// an event in another object... keeping track of what it's listening to
// for easier unbinding later.
Events.listenTo = function(obj, name, callback) {
if (!obj) return this;
var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
var listeningTo = this._listeningTo || (this._listeningTo = {});
var listening = listeningTo[id];
// This object is not listening to any other events on `obj` yet.
// Setup the necessary references to track the listening callbacks.
if (!listening) {
var thisId = this._listenId || (this._listenId = _.uniqueId('l'));
listening = listeningTo[id] = {obj: obj, objId: id, id: thisId, listeningTo: listeningTo, count: 0};
}
// Bind callbacks on obj, and keep track of them on listening.
internalOn(obj, name, callback, this, listening);
return this;
};
// The reducing API that adds a callback to the `events` object.
var onApi = function(events, name, callback, options) {
if (callback) {
var handlers = events[name] || (events[name] = []);
var context = options.context, ctx = options.ctx, listening = options.listening;
if (listening) listening.count++;
handlers.push({ callback: callback, context: context, ctx: context || ctx, listening: listening });
}
return events;
};
// Remove one or many callbacks. If `context` is null, removes all
// callbacks with that function. If `callback` is null, removes all
// callbacks for the event. If `name` is null, removes all bound
// callbacks for all events.
Events.off = function(name, callback, context) {
if (!this._events) return this;
this._events = eventsApi(offApi, this._events, name, callback, {
context: context,
listeners: this._listeners
});
return this;
};
// Tell this object to stop listening to either specific events ... or
// to every object it's currently listening to.
Events.stopListening = function(obj, name, callback) {
var listeningTo = this._listeningTo;
if (!listeningTo) return this;
var ids = obj ? [obj._listenId] : _.keys(listeningTo);
for (var i = 0; i < ids.length; i++) {
var listening = listeningTo[ids[i]];
// If listening doesn't exist, this object is not currently
// listening to obj. Break out early.
if (!listening) break;
listening.obj.off(name, callback, this);
}
if (_.isEmpty(listeningTo)) this._listeningTo = void 0;
return this;
};
// The reducing API that removes a callback from the `events` object.
var offApi = function(events, name, callback, options) {
if (!events) return;
var i = 0, listening;
var context = options.context, listeners = options.listeners;
// Delete all events listeners and "drop" events.
if (!name && !callback && !context) {
var ids = _.keys(listeners);
for (; i < ids.length; i++) {
listening = listeners[ids[i]];
delete listeners[listening.id];
delete listening.listeningTo[listening.objId];
}
return;
}
var names = name ? [name] : _.keys(events);
for (; i < names.length; i++) {
name = names[i];
var handlers = events[name];
// Bail out if there are no events stored.
if (!handlers) break;
// Replace events if there are any remaining. Otherwise, clean up.
var remaining = [];
for (var j = 0; j < handlers.length; j++) {
var handler = handlers[j];
if (
callback && callback !== handler.callback &&
callback !== handler.callback._callback ||
context && context !== handler.context
) {
remaining.push(handler);
} else {
listening = handler.listening;
if (listening && --listening.count === 0) {
delete listeners[listening.id];
delete listening.listeningTo[listening.objId];
}
}
}
// Update tail event if the list has any events. Otherwise, clean up.
if (remaining.length) {
events[name] = remaining;
} else {
delete events[name];
}
}
if (_.size(events)) return events;
};
// Bind an event to only be triggered a single time. After the first time
// the callback is invoked, its listener will be removed. If multiple events
// are passed in using the space-separated syntax, the handler will fire
// once for each event, not once for a combination of all events.
Events.once = function(name, callback, context) {
// Map the event into a `{event: once}` object.
var events = eventsApi(onceMap, {}, name, callback, _.bind(this.off, this));
return this.on(events, void 0, context);
};
// Inversion-of-control versions of `once`.
Events.listenToOnce = function(obj, name, callback) {
// Map the event into a `{event: once}` object.
var events = eventsApi(onceMap, {}, name, callback, _.bind(this.stopListening, this, obj));
return this.listenTo(obj, events);
};
// Reduces the event callbacks into a map of `{event: onceWrapper}`.
// `offer` unbinds the `onceWrapper` after it has been called.
var onceMap = function(map, name, callback, offer) {
if (callback) {
var once = map[name] = _.once(function() {
offer(name, once);
callback.apply(this, arguments);
});
once._callback = callback;
}
return map;
};
// Trigger one or many events, firing all bound callbacks. Callbacks are
// passed the same arguments as `trigger` is, apart from the event name
// (unless you're listening on `"all"`, which will cause your callback to
// receive the true name of the event as the first argument).
Events.trigger = function(name) {
if (!this._events) return this;
var length = Math.max(0, arguments.length - 1);
var args = Array(length);
for (var i = 0; i < length; i++) args[i] = arguments[i + 1];
eventsApi(triggerApi, this._events, name, void 0, args);
return this;
};
// Handles triggering the appropriate event callbacks.
var triggerApi = function(objEvents, name, cb, args) {
if (objEvents) {
var events = objEvents[name];
var allEvents = objEvents.all;
if (events && allEvents) allEvents = allEvents.slice();
if (events) triggerEvents(events, args);
if (allEvents) triggerEvents(allEvents, [name].concat(args));
}
return objEvents;
};
// A difficult-to-believe, but optimized internal dispatch function for
// triggering events. Tries to keep the usual cases speedy (most internal
// Backbone events have 3 arguments).
var triggerEvents = function(events, args) {
var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
switch (args.length) {
case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
}
};
// Aliases for backwards compatibility.
Events.bind = Events.on;
Events.unbind = Events.off;
// Allow the `Backbone` object to serve as a global event bus, for folks who
// want global "pubsub" in a convenient place.
_.extend(Backbone, Events);
// Backbone.Model
// --------------
// Backbone **Models** are the basic data object in the framework --
// frequently representing a row in a table in a database on your server.
// A discrete chunk of data and a bunch of useful, related methods for
// performing computations and transformations on that data.
// Create a new model with the specified attributes. A client id (`cid`)
// is automatically generated and assigned for you.
var Model = Backbone.Model = function(attributes, options) {
var attrs = attributes || {};
options || (options = {});
this.cid = _.uniqueId(this.cidPrefix);
this.attributes = {};
if (options.collection) this.collection = options.collection;
if (options.parse) attrs = this.parse(attrs, options) || {};
attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
this.set(attrs, options);
this.changed = {};
this.initialize.apply(this, arguments);
};
// Attach all inheritable methods to the Model prototype.
_.extend(Model.prototype, Events, {
// A hash of attributes whose current and previous value differ.
changed: null,
// The value returned during the last failed validation.
validationError: null,
// The default name for the JSON `id` attribute is `"id"`. MongoDB and
// CouchDB users may want to set this to `"_id"`.
idAttribute: 'id',
// The prefix is used to create the client id which is used to identify models locally.
// You may want to override this if you're experiencing name clashes with model ids.
cidPrefix: 'c',
// Initialize is an empty function by default. Override it with your own
// initialization logic.
initialize: function(){},
// Return a copy of the model's `attributes` object.
toJSON: function(options) {
return _.clone(this.attributes);
},
// Proxy `Backbone.sync` by default -- but override this if you need
// custom syncing semantics for *this* particular model.
sync: function() {
return Backbone.sync.apply(this, arguments);
},
// Get the value of an attribute.
get: function(attr) {
return this.attributes[attr];
},
// Get the HTML-escaped value of an attribute.
escape: function(attr) {
return _.escape(this.get(attr));
},
// Returns `true` if the attribute contains a value that is not null
// or undefined.
has: function(attr) {
return this.get(attr) != null;
},
// Special-cased proxy to underscore's `_.matches` method.
matches: function(attrs) {
return !!_.iteratee(attrs, this)(this.attributes);
},
// Set a hash of model attributes on the object, firing `"change"`. This is
// the core primitive operation of a model, updating the data and notifying
// anyone who needs to know about the change in state. The heart of the beast.
set: function(key, val, options) {
if (key == null) return this;
// Handle both `"key", value` and `{key: value}` -style arguments.
var attrs;
if (typeof key === 'object') {
attrs = key;
options = val;
} else {
(attrs = {})[key] = val;
}
options || (options = {});
// Run validation.
if (!this._validate(attrs, options)) return false;
// Extract attributes and options.
var unset = options.unset;
var silent = options.silent;
var changes = [];
var changing = this._changing;
this._changing = true;
if (!changing) {
this._previousAttributes = _.clone(this.attributes);
this.changed = {};
}
var current = this.attributes;
var changed = this.changed;
var prev = this._previousAttributes;
// For each `set` attribute, update or delete the current value.
for (var attr in attrs) {
val = attrs[attr];
if (!_.isEqual(current[attr], val)) changes.push(attr);
if (!_.isEqual(prev[attr], val)) {
changed[attr] = val;
} else {
delete changed[attr];
}
unset ? delete current[attr] : current[attr] = val;
}
// Update the `id`.
this.id = this.get(this.idAttribute);
// Trigger all relevant attribute changes.
if (!silent) {
if (changes.length) this._pending = options;
for (var i = 0; i < changes.length; i++) {
this.trigger('change:' + changes[i], this, current[changes[i]], options);
}
}
// You might be wondering why there's a `while` loop here. Changes can
// be recursively nested within `"change"` events.
if (changing) return this;
if (!silent) {
while (this._pending) {
options = this._pending;
this._pending = false;
this.trigger('change', this, options);
}
}
this._pending = false;
this._changing = false;
return this;
},
// Remove an attribute from the model, firing `"change"`. `unset` is a noop
// if the attribute doesn't exist.
unset: function(attr, options) {
return this.set(attr, void 0, _.extend({}, options, {unset: true}));
},
// Clear all attributes on the model, firing `"change"`.
clear: function(options) {
var attrs = {};
for (var key in this.attributes) attrs[key] = void 0;
return this.set(attrs, _.extend({}, options, {unset: true}));
},
// Determine if the model has changed since the last `"change"` event.
// If you specify an attribute name, determine if that attribute has changed.
hasChanged: function(attr) {
if (attr == null) return !_.isEmpty(this.changed);
return _.has(this.changed, attr);
},
// Return an object containing all the attributes that have changed, or
// false if there are no changed attributes. Useful for determining what
// parts of a view need to be updated and/or what attributes need to be
// persisted to the server. Unset attributes will be set to undefined.
// You can also pass an attributes object to diff against the model,
// determining if there *would be* a change.
changedAttributes: function(diff) {
if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
var old = this._changing ? this._previousAttributes : this.attributes;
var changed = {};
for (var attr in diff) {
var val = diff[attr];
if (_.isEqual(old[attr], val)) continue;
changed[attr] = val;
}
return _.size(changed) ? changed : false;
},
// Get the previous value of an attribute, recorded at the time the last
// `"change"` event was fired.
previous: function(attr) {
if (attr == null || !this._previousAttributes) return null;
return this._previousAttributes[attr];
},
// Get all of the attributes of the model at the time of the previous
// `"change"` event.
previousAttributes: function() {
return _.clone(this._previousAttributes);
},
// Fetch the model from the server, merging the response with the model's
// local attributes. Any changed attributes will trigger a "change" event.
fetch: function(options) {
options = _.extend({parse: true}, options);
var model = this;
var success = options.success;
options.success = function(resp) {
var serverAttrs = options.parse ? model.parse(resp, options) : resp;
if (!model.set(serverAttrs, options)) return false;
if (success) success.call(options.context, model, resp, options);
model.trigger('sync', model, resp, options);
};
wrapError(this, options);
return this.sync('read', this, options);
},
// Set a hash of model attributes, and sync the model to the server.
// If the server returns an attributes hash that differs, the model's
// state will be `set` again.
save: function(key, val, options) {
// Handle both `"key", value` and `{key: value}` -style arguments.
var attrs;
if (key == null || typeof key === 'object') {
attrs = key;
options = val;
} else {
(attrs = {})[key] = val;
}
options = _.extend({validate: true, parse: true}, options);
var wait = options.wait;
// If we're not waiting and attributes exist, save acts as
// `set(attr).save(null, opts)` with validation. Otherwise, check if
// the model will be valid when the attributes, if any, are set.
if (attrs && !wait) {
if (!this.set(attrs, options)) return false;
} else {
if (!this._validate(attrs, options)) return false;
}
// After a successful server-side save, the client is (optionally)
// updated with the server-side state.
var model = this;
var success = options.success;
var attributes = this.attributes;
options.success = function(resp) {
// Ensure attributes are restored during synchronous saves.
model.attributes = attributes;
var serverAttrs = options.parse ? model.parse(resp, options) : resp;
if (wait) serverAttrs = _.extend({}, attrs, serverAttrs);
if (serverAttrs && !model.set(serverAttrs, options)) return false;
if (success) success.call(options.context, model, resp, options);
model.trigger('sync', model, resp, options);
};
wrapError(this, options);
// Set temporary attributes if `{wait: true}` to properly find new ids.
if (attrs && wait) this.attributes = _.extend({}, attributes, attrs);
var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
if (method === 'patch' && !options.attrs) options.attrs = attrs;
var xhr = this.sync(method, this, options);
// Restore attributes.
this.attributes = attributes;
return xhr;
},
// Destroy this model on the server if it was already persisted.
// Optimistically removes the model from its collection, if it has one.
// If `wait: true` is passed, waits for the server to respond before removal.
destroy: function(options) {
options = options ? _.clone(options) : {};
var model = this;
var success = options.success;
var wait = options.wait;
var destroy = function() {
model.stopListening();
model.trigger('destroy', model, model.collection, options);
};
options.success = function(resp) {
if (wait) destroy();
if (success) success.call(options.context, model, resp, options);
if (!model.isNew()) model.trigger('sync', model, resp, options);
};
var xhr = false;
if (this.isNew()) {
_.defer(options.success);
} else {
wrapError(this, options);
xhr = this.sync('delete', this, options);
}
if (!wait) destroy();
return xhr;
},
// Default URL for the model's representation on the server -- if you're
// using Backbone's restful methods, override this to change the endpoint
// that will be called.
url: function() {
var base =
_.result(this, 'urlRoot') ||
_.result(this.collection, 'url') ||
urlError();
if (this.isNew()) return base;
var id = this.get(this.idAttribute);
return base.replace(/[^\/]$/, '$&/') + encodeURIComponent(id);
},
// **parse** converts a response into the hash of attributes to be `set` on
// the model. The default implementation is just to pass the response along.
parse: function(resp, options) {
return resp;
},
// Create a new model with identical attributes to this one.
clone: function() {
return new this.constructor(this.attributes);
},
// A model is new if it has never been saved to the server, and lacks an id.
isNew: function() {
return !this.has(this.idAttribute);
},
// Check if the model is currently in a valid state.
isValid: function(options) {
return this._validate({}, _.defaults({validate: true}, options));
},
// Run validation against the next complete set of model attributes,
// returning `true` if all is well. Otherwise, fire an `"invalid"` event.
_validate: function(attrs, options) {
if (!options.validate || !this.validate) return true;
attrs = _.extend({}, this.attributes, attrs);
var error = this.validationError = this.validate(attrs, options) || null;
if (!error) return true;
this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
return false;
}
});
// Underscore methods that we want to implement on the Model, mapped to the
// number of arguments they take.
var modelMethods = { keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
omit: 0, chain: 1, isEmpty: 1 };
// Mix in each Underscore method as a proxy to `Model#attributes`.
addUnderscoreMethods(Model, modelMethods, 'attributes');
// Backbone.Collection
// -------------------
// If models tend to represent a single row of data, a Backbone Collection is
// more analogous to a table full of data ... or a small slice or page of that
// table, or a collection of rows that belong together for a particular reason
// -- all of the messages in this particular folder, all of the documents
// belonging to this particular author, and so on. Collections maintain
// indexes of their models, both in order, and for lookup by `id`.
// Create a new **Collection**, perhaps to contain a specific type of `model`.
// If a `comparator` is specified, the Collection will maintain
// its models in sort order, as they're added and removed.
var Collection = Backbone.Collection = function(models, options) {
options || (options = {});
if (options.model) this.model = options.model;
if (options.comparator !== void 0) this.comparator = options.comparator;
this._reset();
this.initialize.apply(this, arguments);
if (models) this.reset(models, _.extend({silent: true}, options));
};
// Default options for `Collection#set`.
var setOptions = {add: true, remove: true, merge: true};
var addOptions = {add: true, remove: false};
// Splices `insert` into `array` at index `at`.
var splice = function(array, insert, at) {
at = Math.min(Math.max(at, 0), array.length);
var tail = Array(array.length - at);
var length = insert.length;
for (var i = 0; i < tail.length; i++) tail[i] = array[i + at];
for (i = 0; i < length; i++) array[i + at] = insert[i];
for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];
};
// Define the Collection's inheritable methods.
_.extend(Collection.prototype, Events, {
// The default model for a collection is just a **Backbone.Model**.
// This should be overridden in most cases.
model: Model,
// Initialize is an empty function by default. Override it with your own
// initialization logic.
initialize: function(){},
// The JSON representation of a Collection is an array of the
// models' attributes.
toJSON: function(options) {
return this.map(function(model) { return model.toJSON(options); });
},
// Proxy `Backbone.sync` by default.
sync: function() {
return Backbone.sync.apply(this, arguments);
},
// Add a model, or list of models to the set. `models` may be Backbone
// Models or raw JavaScript objects to be converted to Models, or any
// combination of the two.
add: function(models, options) {
return this.set(models, _.extend({merge: false}, options, addOptions));
},
// Remove a model, or a list of models from the set.
remove: function(models, options) {
options = _.extend({}, options);
var singular = !_.isArray(models);
models = singular ? [models] : _.clone(models);
var removed = this._removeModels(models, options);
if (!options.silent && removed) this.trigger('update', this, options);
return singular ? removed[0] : removed;
},
// Update a collection by `set`-ing a new list of models, adding new ones,
// removing models that are no longer present, and merging models that
// already exist in the collection, as necessary. Similar to **Model#set**,
// the core operation for updating the data contained by the collection.
set: function(models, options) {
if (models == null) return;
options = _.defaults({}, options, setOptions);
if (options.parse && !this._isModel(models)) models = this.parse(models, options);
var singular = !_.isArray(models);
models = singular ? [models] : models.slice();
var at = options.at;
if (at != null) at = +at;
if (at < 0) at += this.length + 1;
var set = [];
var toAdd = [];
var toRemove = [];
var modelMap = {};
var add = options.add;
var merge = options.merge;
var remove = options.remove;
var sort = false;
var sortable = this.comparator && (at == null) && options.sort !== false;
var sortAttr = _.isString(this.comparator) ? this.comparator : null;
// Turn bare objects into model references, and prevent invalid models
// from being added.
var model;
for (var i = 0; i < models.length; i++) {
model = models[i];
// If a duplicate is found, prevent it from being added and
// optionally merge it into the existing model.
var existing = this.get(model);
if (existing) {
if (merge && model !== existing) {
var attrs = this._isModel(model) ? model.attributes : model;
if (options.parse) attrs = existing.parse(attrs, options);
existing.set(attrs, options);
if (sortable && !sort) sort = existing.hasChanged(sortAttr);
}
if (!modelMap[existing.cid]) {
modelMap[existing.cid] = true;
set.push(existing);
}
models[i] = existing;
// If this is a new, valid model, push it to the `toAdd` list.
} else if (add) {
model = models[i] = this._prepareModel(model, options);
if (model) {
toAdd.push(model);
this._addReference(model, options);
modelMap[model.cid] = true;
set.push(model);
}
}
}
// Remove stale models.
if (remove) {
for (i = 0; i < this.length; i++) {
model = this.models[i];
if (!modelMap[model.cid]) toRemove.push(model);
}
if (toRemove.length) this._removeModels(toRemove, options);
}
// See if sorting is needed, update `length` and splice in new models.
var orderChanged = false;
var replace = !sortable && add && remove;
if (set.length && replace) {
orderChanged = this.length != set.length || _.some(this.models, function(model, index) {
return model !== set[index];
});
this.models.length = 0;
splice(this.models, set, 0);
this.length = this.models.length;
} else if (toAdd.length) {
if (sortable) sort = true;
splice(this.models, toAdd, at == null ? this.length : at);
this.length = this.models.length;
}
// Silently sort the collection if appropriate.
if (sort) this.sort({silent: true});
// Unless silenced, it's time to fire all appropriate add/sort events.
if (!options.silent) {
for (i = 0; i < toAdd.length; i++) {
if (at != null) options.index = at + i;
model = toAdd[i];
model.trigger('add', model, this, options);
}
if (sort || orderChanged) this.trigger('sort', this, options);
if (toAdd.length || toRemove.length) this.trigger('update', this, options);
}
// Return the added (or merged) model (or models).
return singular ? models[0] : models;
},
// When you have more items than you want to add or remove individually,
// you can reset the entire set with a new list of models, without firing
// any granular `add` or `remove` events. Fires `reset` when finished.
// Useful for bulk operations and optimizations.
reset: function(models, options) {
options = options ? _.clone(options) : {};
for (var i = 0; i < this.models.length; i++) {
this._removeReference(this.models[i], options);
}
options.previousModels = this.models;
this._reset();
models = this.add(models, _.extend({silent: true}, options));
if (!options.silent) this.trigger('reset', this, options);
return models;
},
// Add a model to the end of the collection.
push: function(model, options) {
return this.add(model, _.extend({at: this.length}, options));
},
// Remove a model from the end of the collection.
pop: function(options) {
var model = this.at(this.length - 1);
return this.remove(model, options);
},
// Add a model to the beginning of the collection.
unshift: function(model, options) {
return this.add(model, _.extend({at: 0}, options));
},
// Remove a model from the beginning of the collection.
shift: function(options) {
var model = this.at(0);
return this.remove(model, options);
},
// Slice out a sub-array of models from the collection.
slice: function() {
return slice.apply(this.models, arguments);
},
// Get a model from the set by id.
get: function(obj) {
if (obj == null) return void 0;
var id = this.modelId(this._isModel(obj) ? obj.attributes : obj);
return this._byId[obj] || this._byId[id] || this._byId[obj.cid];
},
// Get the model at the given index.
at: function(index) {
if (index < 0) index += this.length;
return this.models[index];
},
// Return models with matching attributes. Useful for simple cases of
// `filter`.
where: function(attrs, first) {
return this[first ? 'find' : 'filter'](attrs);
},
// Return the first model with matching attributes. Useful for simple cases
// of `find`.
findWhere: function(attrs) {
return this.where(attrs, true);
},
// Force the collection to re-sort itself. You don't need to call this under
// normal circumstances, as the set will maintain sort order as each item
// is added.
sort: function(options) {
var comparator = this.comparator;
if (!comparator) throw new Error('Cannot sort a set without a comparator');
options || (options = {});
var length = comparator.length;
if (_.isFunction(comparator)) comparator = _.bind(comparator, this);
// Run sort based on type of `comparator`.
if (length === 1 || _.isString(comparator)) {
this.models = this.sortBy(comparator);
} else {
this.models.sort(comparator);
}
if (!options.silent) this.trigger('sort', this, options);
return this;
},
// Pluck an attribute from each model in the collection.
pluck: function(attr) {
return _.invoke(this.models, 'get', attr);
},
// Fetch the default set of models for this collection, resetting the
// collection when they arrive. If `reset: true` is passed, the response
// data will be passed through the `reset` method instead of `set`.
fetch: function(options) {
options = _.extend({parse: true}, options);
var success = options.success;
var collection = this;
options.success = function(resp) {
var method = options.reset ? 'reset' : 'set';
collection[method](resp, options);
if (success) success.call(options.context, collection, resp, options);
collection.trigger('sync', collection, resp, options);
};
wrapError(this, options);
return this.sync('read', this, options);
},
// Create a new instance of a model in this collection. Add the model to the
// collection immediately, unless `wait: true` is passed, in which case we
// wait for the server to agree.
create: function(model, options) {
options = options ? _.clone(options) : {};
var wait = options.wait;
model = this._prepareModel(model, options);
if (!model) return false;
if (!wait) this.add(model, options);
var collection = this;
var success = options.success;
options.success = function(model, resp, callbackOpts) {
if (wait) collection.add(model, callbackOpts);
if (success) success.call(callbackOpts.context, model, resp, callbackOpts);
};
model.save(null, options);
return model;
},
// **parse** converts a response into a list of models to be added to the
// collection. The default implementation is just to pass it through.
parse: function(resp, options) {
return resp;
},
// Create a new collection with an identical list of models as this one.
clone: function() {
return new this.constructor(this.models, {
model: this.model,
comparator: this.comparator
});
},
// Define how to uniquely identify models in the collection.
modelId: function (attrs) {
return attrs[this.model.prototype.idAttribute || 'id'];
},
// Private method to reset all internal state. Called when the collection
// is first initialized or reset.
_reset: function() {
this.length = 0;
this.models = [];
this._byId = {};
},
// Prepare a hash of attributes (or other model) to be added to this
// collection.
_prepareModel: function(attrs, options) {
if (this._isModel(attrs)) {
if (!attrs.collection) attrs.collection = this;
return attrs;
}
options = options ? _.clone(options) : {};
options.collection = this;
var model = new this.model(attrs, options);
if (!model.validationError) return model;
this.trigger('invalid', this, model.validationError, options);
return false;
},
// Internal method called by both remove and set.
_removeModels: function(models, options) {
var removed = [];
for (var i = 0; i < models.length; i++) {
var model = this.get(models[i]);
if (!model) continue;
var index = this.indexOf(model);
this.models.splice(index, 1);
this.length--;
if (!options.silent) {
options.index = index;
model.trigger('remove', model, this, options);
}
removed.push(model);
this._removeReference(model, options);
}
return removed.length ? removed : false;
},
// Method for checking whether an object should be considered a model for
// the purposes of adding to the collection.
_isModel: function (model) {
return model instanceof Model;
},
// Internal method to create a model's ties to a collection.
_addReference: function(model, options) {
this._byId[model.cid] = model;
var id = this.modelId(model.attributes);
if (id != null) this._byId[id] = model;
model.on('all', this._onModelEvent, this);
},
// Internal method to sever a model's ties to a collection.
_removeReference: function(model, options) {
delete this._byId[model.cid];
var id = this.modelId(model.attributes);
if (id != null) delete this._byId[id];
if (this === model.collection) delete model.collection;
model.off('all', this._onModelEvent, this);
},
// Internal method called every time a model in the set fires an event.
// Sets need to update their indexes when models change ids. All other
// events simply proxy through. "add" and "remove" events that originate
// in other collections are ignored.
_onModelEvent: function(event, model, collection, options) {
if ((event === 'add' || event === 'remove') && collection !== this) return;
if (event === 'destroy') this.remove(model, options);
if (event === 'change') {
var prevId = this.modelId(model.previousAttributes());
var id = this.modelId(model.attributes);
if (prevId !== id) {
if (prevId != null) delete this._byId[prevId];
if (id != null) this._byId[id] = model;
}
}
this.trigger.apply(this, arguments);
}
});
// Underscore methods that we want to implement on the Collection.
// 90% of the core usefulness of Backbone Collections is actually implemented
// right here:
var collectionMethods = { forEach: 3, each: 3, map: 3, collect: 3, reduce: 4,
foldl: 4, inject: 4, reduceRight: 4, foldr: 4, find: 3, detect: 3, filter: 3,
select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,
contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,
sortBy: 3, indexBy: 3};
// Mix in each Underscore method as a proxy to `Collection#models`.
addUnderscoreMethods(Collection, collectionMethods, 'models');
// Backbone.View
// -------------
// Backbone Views are almost more convention than they are actual code. A View
// is simply a JavaScript object that represents a logical chunk of UI in the
// DOM. This might be a single item, an entire list, a sidebar or panel, or
// even the surrounding frame which wraps your whole app. Defining a chunk of
// UI as a **View** allows you to define your DOM events declaratively, without
// having to worry about render order ... and makes it easy for the view to
// react to specific changes in the state of your models.
// Creating a Backbone.View creates its initial element outside of the DOM,
// if an existing element is not provided...
var View = Backbone.View = function(options) {
this.cid = _.uniqueId('view');
_.extend(this, _.pick(options, viewOptions));
this._ensureElement();
this.initialize.apply(this, arguments);
};
// Cached regex to split keys for `delegate`.
var delegateEventSplitter = /^(\S+)\s*(.*)$/;
// List of view options to be set as properties.
var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
// Set up all inheritable **Backbone.View** properties and methods.
_.extend(View.prototype, Events, {
// The default `tagName` of a View's element is `"div"`.
tagName: 'div',
// jQuery delegate for element lookup, scoped to DOM elements within the
// current view. This should be preferred to global lookups where possible.
$: function(selector) {
return this.$el.find(selector);
},
// Initialize is an empty function by default. Override it with your own
// initialization logic.
initialize: function(){},
// **render** is the core function that your view should override, in order
// to populate its element (`this.el`), with the appropriate HTML. The
// convention is for **render** to always return `this`.
render: function() {
return this;
},
// Remove this view by taking the element out of the DOM, and removing any
// applicable Backbone.Events listeners.
remove: function() {
this._removeElement();
this.stopListening();
return this;
},
// Remove this view's element from the document and all event listeners
// attached to it. Exposed for subclasses using an alternative DOM
// manipulation API.
_removeElement: function() {
this.$el.remove();
},
// Change the view's element (`this.el` property) and re-delegate the
// view's events on the new element.
setElement: function(element) {
this.undelegateEvents();
this._setElement(element);
this.delegateEvents();
return this;
},
// Creates the `this.el` and `this.$el` references for this view using the
// given `el`. `el` can be a CSS selector or an HTML string, a jQuery
// context or an element. Subclasses can override this to utilize an
// alternative DOM manipulation API and are only required to set the
// `this.el` property.
_setElement: function(el) {
this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
this.el = this.$el[0];
},
// Set callbacks, where `this.events` is a hash of
//
// *{"event selector": "callback"}*
//
// {
// 'mousedown .title': 'edit',
// 'click .button': 'save',
// 'click .open': function(e) { ... }
// }
//
// pairs. Callbacks will be bound to the view, with `this` set properly.
// Uses event delegation for efficiency.
// Omitting the selector binds the event to `this.el`.
delegateEvents: function(events) {
events || (events = _.result(this, 'events'));
if (!events) return this;
this.undelegateEvents();
for (var key in events) {
var method = events[key];
if (!_.isFunction(method)) method = this[method];
if (!method) continue;
var match = key.match(delegateEventSplitter);
this.delegate(match[1], match[2], _.bind(method, this));
}
return this;
},
// Add a single event listener to the view's element (or a child element
// using `selector`). This only works for delegate-able events: not `focus`,
// `blur`, and not `change`, `submit`, and `reset` in Internet Explorer.
delegate: function(eventName, selector, listener) {
this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
return this;
},
// Clears all callbacks previously bound to the view by `delegateEvents`.
// You usually don't need to use this, but may wish to if you have multiple
// Backbone views attached to the same DOM element.
undelegateEvents: function() {
if (this.$el) this.$el.off('.delegateEvents' + this.cid);
return this;
},
// A finer-grained `undelegateEvents` for removing a single delegated event.
// `selector` and `listener` are both optional.
undelegate: function(eventName, selector, listener) {
this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);
return this;
},
// Produces a DOM element to be assigned to your view. Exposed for
// subclasses using an alternative DOM manipulation API.
_createElement: function(tagName) {
return document.createElement(tagName);
},
// Ensure that the View has a DOM element to render into.
// If `this.el` is a string, pass it through `$()`, take the first
// matching element, and re-assign it to `el`. Otherwise, create
// an element from the `id`, `className` and `tagName` properties.
_ensureElement: function() {
if (!this.el) {
var attrs = _.extend({}, _.result(this, 'attributes'));
if (this.id) attrs.id = _.result(this, 'id');
if (this.className) attrs['class'] = _.result(this, 'className');
this.setElement(this._createElement(_.result(this, 'tagName')));
this._setAttributes(attrs);
} else {
this.setElement(_.result(this, 'el'));
}
},
// Set attributes from a hash on this view's element. Exposed for
// subclasses using an alternative DOM manipulation API.
_setAttributes: function(attributes) {
this.$el.attr(attributes);
}
});
// Backbone.sync
// -------------
// Override this function to change the manner in which Backbone persists
// models to the server. You will be passed the type of request, and the
// model in question. By default, makes a RESTful Ajax request
// to the model's `url()`. Some possible customizations could be:
//
// * Use `setTimeout` to batch rapid-fire updates into a single request.
// * Send up the models as XML instead of JSON.
// * Persist models via WebSockets instead of Ajax.
//
// Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
// as `POST`, with a `_method` parameter containing the true HTTP method,
// as well as all requests with the body as `application/x-www-form-urlencoded`
// instead of `application/json` with the model in a param named `model`.
// Useful when interfacing with server-side languages like **PHP** that make
// it difficult to read the body of `PUT` requests.
Backbone.sync = function(method, model, options) {
var type = methodMap[method];
// Default options, unless specified.
_.defaults(options || (options = {}), {
emulateHTTP: Backbone.emulateHTTP,
emulateJSON: Backbone.emulateJSON
});
// Default JSON-request options.
var params = {type: type, dataType: 'json'};
// Ensure that we have a URL.
if (!options.url) {
params.url = _.result(model, 'url') || urlError();
}
// Ensure that we have the appropriate request data.
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
params.contentType = 'application/json';
params.data = JSON.stringify(options.attrs || model.toJSON(options));
}
// For older servers, emulate JSON by encoding the request into an HTML-form.
if (options.emulateJSON) {
params.contentType = 'application/x-www-form-urlencoded';
params.data = params.data ? {model: params.data} : {};
}
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
// And an `X-HTTP-Method-Override` header.
if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
params.type = 'POST';
if (options.emulateJSON) params.data._method = type;
var beforeSend = options.beforeSend;
options.beforeSend = function(xhr) {
xhr.setRequestHeader('X-HTTP-Method-Override', type);
if (beforeSend) return beforeSend.apply(this, arguments);
};
}
// Don't process data on a non-GET request.
if (params.type !== 'GET' && !options.emulateJSON) {
params.processData = false;
}
// Pass along `textStatus` and `errorThrown` from jQuery.
var error = options.error;
options.error = function(xhr, textStatus, errorThrown) {
options.textStatus = textStatus;
options.errorThrown = errorThrown;
if (error) error.call(options.context, xhr, textStatus, errorThrown);
};
// Make the request, allowing the user to override any Ajax options.
var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
model.trigger('request', model, xhr, options);
return xhr;
};
// Map from CRUD to HTTP for our default `Backbone.sync` implementation.
var methodMap = {
'create': 'POST',
'update': 'PUT',
'patch': 'PATCH',
'delete': 'DELETE',
'read': 'GET'
};
// Set the default implementation of `Backbone.ajax` to proxy through to `$`.
// Override this if you'd like to use a different library.
Backbone.ajax = function() {
return Backbone.$.ajax.apply(Backbone.$, arguments);
};
// Backbone.Router
// ---------------
// Routers map faux-URLs to actions, and fire events when routes are
// matched. Creating a new one sets its `routes` hash, if not set statically.
var Router = Backbone.Router = function(options) {
options || (options = {});
if (options.routes) this.routes = options.routes;
this._bindRoutes();
this.initialize.apply(this, arguments);
};
// Cached regular expressions for matching named param parts and splatted
// parts of route strings.
var optionalParam = /\((.*?)\)/g;
var namedParam = /(\(\?)?:\w+/g;
var splatParam = /\*\w+/g;
var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
// Set up all inheritable **Backbone.Router** properties and methods.
_.extend(Router.prototype, Events, {
// Initialize is an empty function by default. Override it with your own
// initialization logic.
initialize: function(){},
// Manually bind a single named route to a callback. For example:
//
// this.route('search/:query/p:num', 'search', function(query, num) {
// ...
// });
//
route: function(route, name, callback) {
if (!_.isRegExp(route)) route = this._routeToRegExp(route);
if (_.isFunction(name)) {
callback = name;
name = '';
}
if (!callback) callback = this[name];
var router = this;
Backbone.history.route(route, function(fragment) {
var args = router._extractParameters(route, fragment);
if (router.execute(callback, args, name) !== false) {
router.trigger.apply(router, ['route:' + name].concat(args));
router.trigger('route', name, args);
Backbone.history.trigger('route', router, name, args);
}
});
return this;
},
// Execute a route handler with the provided parameters. This is an
// excellent place to do pre-route setup or post-route cleanup.
execute: function(callback, args, name) {
if (callback) callback.apply(this, args);
},
// Simple proxy to `Backbone.history` to save a fragment into the history.
navigate: function(fragment, options) {
Backbone.history.navigate(fragment, options);
return this;
},
// Bind all defined routes to `Backbone.history`. We have to reverse the
// order of the routes here to support behavior where the most general
// routes can be defined at the bottom of the route map.
_bindRoutes: function() {
if (!this.routes) return;
this.routes = _.result(this, 'routes');
var route, routes = _.keys(this.routes);
while ((route = routes.pop()) != null) {
this.route(route, this.routes[route]);
}
},
// Convert a route string into a regular expression, suitable for matching
// against the current location hash.
_routeToRegExp: function(route) {
route = route.replace(escapeRegExp, '\\$&')
.replace(optionalParam, '(?:$1)?')
.replace(namedParam, function(match, optional) {
return optional ? match : '([^/?]+)';
})
.replace(splatParam, '([^?]*?)');
return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
},
// Given a route, and a URL fragment that it matches, return the array of
// extracted decoded parameters. Empty or unmatched parameters will be
// treated as `null` to normalize cross-browser behavior.
_extractParameters: function(route, fragment) {
var params = route.exec(fragment).slice(1);
return _.map(params, function(param, i) {
// Don't decode the search params.
if (i === params.length - 1) return param || null;
return param ? decodeURIComponent(param) : null;
});
}
});
// Backbone.History
// ----------------
// Handles cross-browser history management, based on either
// [pushState](http://diveintohtml5.info/history.html) and real URLs, or
// [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
// and URL fragments. If the browser supports neither (old IE, natch),
// falls back to polling.
var History = Backbone.History = function() {
this.handlers = [];
this.checkUrl = _.bind(this.checkUrl, this);
// Ensure that `History` can be used outside of the browser.
if (typeof window !== 'undefined') {
this.location = window.location;
this.history = window.history;
}
};
// Cached regex for stripping a leading hash/slash and trailing space.
var routeStripper = /^[#\/]|\s+$/g;
// Cached regex for stripping leading and trailing slashes.
var rootStripper = /^\/+|\/+$/g;
// Cached regex for stripping urls of hash.
var pathStripper = /#.*$/;
// Has the history handling already been started?
History.started = false;
// Set up all inheritable **Backbone.History** properties and methods.
_.extend(History.prototype, Events, {
// The default interval to poll for hash changes, if necessary, is
// twenty times a second.
interval: 50,
// Are we at the app root?
atRoot: function() {
var path = this.location.pathname.replace(/[^\/]$/, '$&/');
return path === this.root && !this.getSearch();
},
// Does the pathname match the root?
matchRoot: function() {
var path = this.decodeFragment(this.location.pathname);
var root = path.slice(0, this.root.length - 1) + '/';
return root === this.root;
},
// Unicode characters in `location.pathname` are percent encoded so they're
// decoded for comparison. `%25` should not be decoded since it may be part
// of an encoded parameter.
decodeFragment: function(fragment) {
return decodeURI(fragment.replace(/%25/g, '%2525'));
},
// In IE6, the hash fragment and search params are incorrect if the
// fragment contains `?`.
getSearch: function() {
var match = this.location.href.replace(/#.*/, '').match(/\?.+/);
return match ? match[0] : '';
},
// Gets the true hash value. Cannot use location.hash directly due to bug
// in Firefox where location.hash will always be decoded.
getHash: function(window) {
var match = (window || this).location.href.match(/#(.*)$/);
return match ? match[1] : '';
},
// Get the pathname and search params, without the root.
getPath: function() {
var path = this.decodeFragment(
this.location.pathname + this.getSearch()
).slice(this.root.length - 1);
return path.charAt(0) === '/' ? path.slice(1) : path;
},
// Get the cross-browser normalized URL fragment from the path or hash.
getFragment: function(fragment) {
if (fragment == null) {
if (this._usePushState || !this._wantsHashChange) {
fragment = this.getPath();
} else {
fragment = this.getHash();
}
}
return fragment.replace(routeStripper, '');
},
// Start the hash change handling, returning `true` if the current URL matches
// an existing route, and `false` otherwise.
start: function(options) {
if (History.started) throw new Error('Backbone.history has already been started');
History.started = true;
// Figure out the initial configuration. Do we need an iframe?
// Is pushState desired ... is it available?
this.options = _.extend({root: '/'}, this.options, options);
this.root = this.options.root;
this._wantsHashChange = this.options.hashChange !== false;
this._hasHashChange = 'onhashchange' in window && (document.documentMode === void 0 || document.documentMode > 7);
this._useHashChange = this._wantsHashChange && this._hasHashChange;
this._wantsPushState = !!this.options.pushState;
this._hasPushState = !!(this.history && this.history.pushState);
this._usePushState = this._wantsPushState && this._hasPushState;
this.fragment = this.getFragment();
// Normalize root to always include a leading and trailing slash.
this.root = ('/' + this.root + '/').replace(rootStripper, '/');
// Transition from hashChange to pushState or vice versa if both are
// requested.
if (this._wantsHashChange && this._wantsPushState) {
// If we've started off with a route from a `pushState`-enabled
// browser, but we're currently in a browser that doesn't support it...
if (!this._hasPushState && !this.atRoot()) {
var root = this.root.slice(0, -1) || '/';
this.location.replace(root + '#' + this.getPath());
// Return immediately as browser will do redirect to new url
return true;
// Or if we've started out with a hash-based route, but we're currently
// in a browser where it could be `pushState`-based instead...
} else if (this._hasPushState && this.atRoot()) {
this.navigate(this.getHash(), {replace: true});
}
}
// Proxy an iframe to handle location events if the browser doesn't
// support the `hashchange` event, HTML5 history, or the user wants
// `hashChange` but not `pushState`.
if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) {
this.iframe = document.createElement('iframe');
this.iframe.src = 'javascript:0';
this.iframe.style.display = 'none';
this.iframe.tabIndex = -1;
var body = document.body;
// Using `appendChild` will throw on IE < 9 if the document is not ready.
var iWindow = body.insertBefore(this.iframe, body.firstChild).contentWindow;
iWindow.document.open();
iWindow.document.close();
iWindow.location.hash = '#' + this.fragment;
}
// Add a cross-platform `addEventListener` shim for older browsers.
var addEventListener = window.addEventListener || function (eventName, listener) {
return attachEvent('on' + eventName, listener);
};
// Depending on whether we're using pushState or hashes, and whether
// 'onhashchange' is supported, determine how we check the URL state.
if (this._usePushState) {
addEventListener('popstate', this.checkUrl, false);
} else if (this._useHashChange && !this.iframe) {
addEventListener('hashchange', this.checkUrl, false);
} else if (this._wantsHashChange) {
this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
}
if (!this.options.silent) return this.loadUrl();
},
// Disable Backbone.history, perhaps temporarily. Not useful in a real app,
// but possibly useful for unit testing Routers.
stop: function() {
// Add a cross-platform `removeEventListener` shim for older browsers.
var removeEventListener = window.removeEventListener || function (eventName, listener) {
return detachEvent('on' + eventName, listener);
};
// Remove window listeners.
if (this._usePushState) {
removeEventListener('popstate', this.checkUrl, false);
} else if (this._useHashChange && !this.iframe) {
removeEventListener('hashchange', this.checkUrl, false);
}
// Clean up the iframe if necessary.
if (this.iframe) {
document.body.removeChild(this.iframe);
this.iframe = null;
}
// Some environments will throw when clearing an undefined interval.
if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
History.started = false;
},
// Add a route to be tested when the fragment changes. Routes added later
// may override previous routes.
route: function(route, callback) {
this.handlers.unshift({route: route, callback: callback});
},
// Checks the current URL to see if it has changed, and if it has,
// calls `loadUrl`, normalizing across the hidden iframe.
checkUrl: function(e) {
var current = this.getFragment();
// If the user pressed the back button, the iframe's hash will have
// changed and we should use that for comparison.
if (current === this.fragment && this.iframe) {
current = this.getHash(this.iframe.contentWindow);
}
if (current === this.fragment) return false;
if (this.iframe) this.navigate(current);
this.loadUrl();
},
// Attempt to load the current URL fragment. If a route succeeds with a
// match, returns `true`. If no defined routes matches the fragment,
// returns `false`.
loadUrl: function(fragment) {
// If the root doesn't match, no routes can match either.
if (!this.matchRoot()) return false;
fragment = this.fragment = this.getFragment(fragment);
return _.some(this.handlers, function(handler) {
if (handler.route.test(fragment)) {
handler.callback(fragment);
return true;
}
});
},
// Save a fragment into the hash history, or replace the URL state if the
// 'replace' option is passed. You are responsible for properly URL-encoding
// the fragment in advance.
//
// The options object can contain `trigger: true` if you wish to have the
// route callback be fired (not usually desirable), or `replace: true`, if
// you wish to modify the current URL without adding an entry to the history.
navigate: function(fragment, options) {
if (!History.started) return false;
if (!options || options === true) options = {trigger: !!options};
// Normalize the fragment.
fragment = this.getFragment(fragment || '');
// Don't include a trailing slash on the root.
var root = this.root;
if (fragment === '' || fragment.charAt(0) === '?') {
root = root.slice(0, -1) || '/';
}
var url = root + fragment;
// Strip the hash and decode for matching.
fragment = this.decodeFragment(fragment.replace(pathStripper, ''));
if (this.fragment === fragment) return;
this.fragment = fragment;
// If pushState is available, we use it to set the fragment as a real URL.
if (this._usePushState) {
this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
// If hash changes haven't been explicitly disabled, update the hash
// fragment to store history.
} else if (this._wantsHashChange) {
this._updateHash(this.location, fragment, options.replace);
if (this.iframe && (fragment !== this.getHash(this.iframe.contentWindow))) {
var iWindow = this.iframe.contentWindow;
// Opening and closing the iframe tricks IE7 and earlier to push a
// history entry on hash-tag change. When replace is true, we don't
// want this.
if (!options.replace) {
iWindow.document.open();
iWindow.document.close();
}
this._updateHash(iWindow.location, fragment, options.replace);
}
// If you've told us that you explicitly don't want fallback hashchange-
// based history, then `navigate` becomes a page refresh.
} else {
return this.location.assign(url);
}
if (options.trigger) return this.loadUrl(fragment);
},
// Update the hash location, either replacing the current entry, or adding
// a new one to the browser history.
_updateHash: function(location, fragment, replace) {
if (replace) {
var href = location.href.replace(/(javascript:|#).*$/, '');
location.replace(href + '#' + fragment);
} else {
// Some browsers require that `hash` contains a leading #.
location.hash = '#' + fragment;
}
}
});
// Create the default Backbone.history.
Backbone.history = new History;
// Helpers
// -------
// Helper function to correctly set up the prototype chain for subclasses.
// Similar to `goog.inherits`, but uses a hash of prototype properties and
// class properties to be extended.
var extend = function(protoProps, staticProps) {
var parent = this;
var child;
// The constructor function for the new subclass is either defined by you
// (the "constructor" property in your `extend` definition), or defaulted
// by us to simply call the parent constructor.
if (protoProps && _.has(protoProps, 'constructor')) {
child = protoProps.constructor;
} else {
child = function(){ return parent.apply(this, arguments); };
}
// Add static properties to the constructor function, if supplied.
_.extend(child, parent, staticProps);
// Set the prototype chain to inherit from `parent`, without calling
// `parent` constructor function.
var Surrogate = function(){ this.constructor = child; };
Surrogate.prototype = parent.prototype;
child.prototype = new Surrogate;
// Add prototype properties (instance properties) to the subclass,
// if supplied.
if (protoProps) _.extend(child.prototype, protoProps);
// Set a convenience property in case the parent's prototype is needed
// later.
child.__super__ = parent.prototype;
return child;
};
// Set up inheritance for the model, collection, router, view and history.
Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
// Throw an error when a URL is needed, and none is supplied.
var urlError = function() {
throw new Error('A "url" property or function must be specified');
};
// Wrap an optional error callback with a fallback error event.
var wrapError = function(model, options) {
var error = options.error;
options.error = function(resp) {
if (error) error.call(options.context, model, resp, options);
model.trigger('error', model, resp, options);
};
};
return Backbone;
}));
CKEditor 4 Changelog
====================
## CKEditor 4.5.11
**Security Updates:**
* [Severity: minor] Fixed the target="_blank" vulnerability reported by James Gaskell.
Issue summary: If a victim had access to a spoofed version of ckeditor.com via HTTP (e.g. due to DNS spoofing, using a hacked public network or mailicious hotspot), then when using a link to the ckeditor.com website it was possible for the attacker to change the current URL of the opening page, even if the opening page was protected with SSL.
An upgrade is recommended.
New Features:
* [#14747](http://dev.ckeditor.com/ticket/14747): The [Enhanced Image](http://ckeditor.com/addon/image2) caption now supports the link `target` attribute.
* [#7154](http://dev.ckeditor.com/ticket/7154): Added support for the "Display Text" field to the [Link](http://ckeditor.com/addon/link) dialog. Thanks to [Ryan Guill](https://github.com/ryanguill)!
Fixed Issues:
* [#13362](http://dev.ckeditor.com/ticket/13362): [Blink, WebKit] Fixed: Active widget element is not cached when it is losing focus and it is inside an editable element.
* [#13755](http://dev.ckeditor.com/ticket/13755): [Edge] Fixed: Pasting images does not work.
* [#13548](http://dev.ckeditor.com/ticket/13548): [IE] Fixed: Clicking the [elements path](http://ckeditor.com/addon/elementspath) disables Cut and Copy icons.
* [#13812](http://dev.ckeditor.com/ticket/13812): Fixed: When aborting file upload the placeholder for image is left.
* [#14659](http://dev.ckeditor.com/ticket/14659): [Blink] Fixed: Content scrolled to the top after closing the dialog in a [`<div>`-based editor](http://ckeditor.com/addon/divarea).
* [#14825](http://dev.ckeditor.com/ticket/14825): [Edge] Fixed: Focusing the editor causes unwanted scrolling due to dropped support for the `setActive` method.
## CKEditor 4.5.10
Fixed Issues:
* [#10750](http://dev.ckeditor.com/ticket/10750): Fixed: The editor does not escape the `font-style` family property correctly, removing quotes and whitespace from font names.
* [#14413](http://dev.ckeditor.com/ticket/14413): Fixed: The [Auto Grow](http://ckeditor.com/addon/autogrow) plugin with the [`config.autoGrow_onStartup`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-autoGrow_onStartup) option set to `true` does not work properly for an editor that is not visible.
* [#14451](http://dev.ckeditor.com/ticket/14451): Fixed: Numeric element ID not escaped properly. Thanks to [Jakub Chalupa](https://github.com/chaluja7)!
* [#14590](http://dev.ckeditor.com/ticket/14590): Fixed: Additional line break appearing after inline elements when switching modes. Thanks to [dpidcock](https://github.com/dpidcock)!
* [#14539](https://dev.ckeditor.com/ticket/14539): Fixed: JAWS reads "selected Blank" instead of "selected <widget name>" when selecting a widget.
* [#14701](http://dev.ckeditor.com/ticket/14701): Fixed: More precise labels for [Enhanced Image](http://ckeditor.com/addon/image2) and [Placeholder](http://ckeditor.com/addon/placeholder) widgets.
* [#14667](http://dev.ckeditor.com/ticket/14667): [IE] Fixed: Removing background color from selected text removes background color from the whole paragraph.
* [#14252](http://dev.ckeditor.com/ticket/14252): [IE] Fixed: Styles drop-down list does not always reflect the current style of the text line.
* [#14275](http://dev.ckeditor.com/ticket/14275): [IE9+] Fixed: `onerror` and `onload` events are not used in browsers it could have been used when loading scripts dynamically.
## CKEditor 4.5.9
Fixed Issues:
* [#10685](http://dev.ckeditor.com/ticket/10685): Fixed: Unreadable toolbar icons after updating to the new editor version. Fixed with [6876179](https://github.com/ckeditor/ckeditor-dev/commit/6876179db4ee97e786b07b8fd72e6b4120732185) in [ckeditor-dev](https://github.com/ckeditor/ckeditor-dev) and [6c9189f4](https://github.com/ckeditor/ckeditor-presets/commit/6c9189f46392d2c126854fe8889b820b8c76d291) in [ckeditor-presets](https://github.com/ckeditor/ckeditor-presets).
* [#14573](https://dev.ckeditor.com/ticket/14573): Fixed: Missing [Widget](http://ckeditor.com/addon/widget) drag handler CSS when there are multiple editor instances.
* [#14620](https://dev.ckeditor.com/ticket/14620): Fixed: Setting both the `min-height` style for the `<body>` element and the `height` style for the `<html>` element breaks the [Auto Grow](http://ckeditor.com/addon/autogrow) plugin.
* [#14538](http://dev.ckeditor.com/ticket/14538): Fixed: Keyboard focus goes into an embedded `<iframe>` element.
* [#14602](http://dev.ckeditor.com/ticket/14602): Fixed: The [`dom.element.removeAttribute()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-removeAttribute) method does not remove all attributes if no parameter is given.
* [#8679](http://dev.ckeditor.com/ticket/8679): Fixed: Better focus indication and ability to style the selected color in the [color picker dialog](http://ckeditor.com/addon/colordialog).
* [#11697](http://dev.ckeditor.com/ticket/11697): Fixed: Content is replaced ignoring the letter case setting in the [Find and Replace](http://ckeditor.com/addon/find) dialog window.
* [#13886](http://dev.ckeditor.com/ticket/13886): Fixed: Invalid handling of the [`CKEDITOR.style`](http://docs.ckeditor.com/#!/api/CKEDITOR.style) instance with the `styles` property by [`CKEDITOR.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter).
* [#14535](http://dev.ckeditor.com/ticket/14535): Fixed: CSS syntax corrections. Thanks to [mdjdenormandie](https://github.com/mdjdenormandie)!
* [#14312](http://dev.ckeditor.com/ticket/14312): [IE] Fixed: Artifact is visible after pasting any text.
## CKEditor 4.5.8
New Features:
* [#12440](http://dev.ckeditor.com/ticket/12440): Added the [`config.colorButton_enableAutomatic`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-colorButton_enableAutomatic) option to allow hiding the "Automatic" option in the [color picker](http://ckeditor.com/addon/colorbutton).
Fixed Issues:
* [#10448](http://dev.ckeditor.com/ticket/10448): Fixed: Lack of scrollbar in the [right-to-left text direction](http://ckeditor.com/addon/bidi).
* [#12707](http://dev.ckeditor.com/ticket/12707): Fixed: The order of table elements does not comply with the HTML specification.
* [#13756](http://dev.ckeditor.com/ticket/13756): [Edge] Fixed: Context menus are cut-off.
## CKEditor 4.5.7
New Features:
* [#14327](http://dev.ckeditor.com/ticket/14327): Added Swiss German localization. Thanks to [Miro Grenda](https://twitter.com/mirogrenda)!
Fixed Issues:
* [#13816](http://dev.ckeditor.com/ticket/13816): Introduced a new strategy for Filling Character handling to avoid changes in DOM. This fixes the following issues:
* [#12727](http://dev.ckeditor.com/ticket/12727): [Blink] `IndexSizeError` when using the [Div Editing Area](http://ckeditor.com/addon/divarea) and [Content Templates](http://ckeditor.com/addon/templates) plugins.
* [#13377](http://dev.ckeditor.com/ticket/13377): [Widget](http://ckeditor.com/addon/widget) plugin issue when typing in Korean.
* [#13389](http://dev.ckeditor.com/ticket/13389): [Blink] [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) fails when the cursor is next to an `<hr>` tag.
* [#13513](http://dev.ckeditor.com/ticket/13513): [Blink, WebKit] [Div Editing Area](http://ckeditor.com/addon/divarea) and [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) throw an error when an image is the only data in the editor.
* [#13884](http://dev.ckeditor.com/ticket/13884): [Firefox] Fixed: Copying and pasting a table results in just the first cell being pasted.
* [#14234](http://dev.ckeditor.com/ticket/14234): Fixed: URL input field is not marked as required in the [Media Embed](http://ckeditor.com/addon/embed) dialog.
## CKEditor 4.5.6
New Features:
* Introduced the [`CKEDITOR.tools.getCookie()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-getCookie) and [`CKEDITOR.tools.setCookie()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-setCookie) methods for accessing cookies.
* Introduced the [`CKEDITOR.tools.getCsrfToken()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-getCsrfToken) method. The CSRF token is now automatically sent by the [File Browser](http://ckeditor.com/addon/filebrowser) and [File Tools](http://ckeditor.com/addon/filetools) plugins during file uploads. The server-side upload handlers may check it and use it to additionally secure the communication.
Other Changes:
* Updated [SCAYT](http://ckeditor.com/addon/scayt) (Spell Check As You Type):
- New features:
- CKEditor [Language](http://ckeditor.com/addon/language) plugin support.
- CKEditor [Placeholder](http://ckeditor.com/addon/placeholder) plugin support.
- [Drag&Drop](http://sdk.ckeditor.com/samples/fileupload.html) support.
- **Experimental** [GRAYT](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-grayt_autoStartup) (Grammar As You Type) functionality.
- Fixed issues:
* [#98](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/98): SCAYT affects dialog double-click. Fixed in SCAYT core.
* [#102](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/102): SCAYT core performance enhancements.
* [#104](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/104): SCAYT's spans leak into the clipboard and after pasting.
* [#105](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/105): A JavaScript error fired in case of multiple instances of CKEditor on one page.
* [#107](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/107): SCAYT should not check non-editable parts of content.
* [#108](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/108): Latest SCAYT copies the ID of the editor element to the iframe.
* SCAYT stops working when CKEditor [Undo plugin](http://ckeditor.com/addon/undo) not enabled.
* Issue with pasting SCAYT markup in CKEditor.
* SCAYT stops working after pressing the *Cancel* button in the WSC dialog.
## CKEditor 4.5.5
Fixed Issues:
* [#13887](https://dev.ckeditor.com/ticket/13887): Fixed: [Link](http://ckeditor.com/addon/link) plugin alters the `target` attribute value. Thanks to [SamZiemer](https://github.com/SamZiemer)!
* [#12189](http://dev.ckeditor.com/ticket/12189): Fixed: The [Link](http://ckeditor.com/addon/link) plugin dialog does not display the subject of email links if the subject parameter is not lowercase.
* [#9192](http://dev.ckeditor.com/ticket/9192): Fixed: An `undefined` string is appended to an email address added with the [Link](http://ckeditor.com/addon/link) plugin if subject and email body are empty and [`config.emailProtection`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-emailProtection) is set to `encode`.
* [#13790](https://dev.ckeditor.com/ticket/13790): Fixed: It is not possible to destroy the editor `<iframe>` after the editor was detached from DOM. Thanks to [Stefan Rijnhart](https://github.com/StefanRijnhart)!
* [#13803](https://dev.ckeditor.com/ticket/13803): Fixed: The editor cannot be destroyed before being fully initialized. Thanks to [Cyril Fluck](https://github.com/cyril-sf)!
* [#13867](http://dev.ckeditor.com/ticket/13867): Fixed: CKEditor does not work when the `classList` polyfill is used.
* [#13885](http://dev.ckeditor.com/ticket/13885): Fixed: [Enhanced Image](http://ckeditor.com/addon/image2) requires the [Link](http://ckeditor.com/addon/link) plugin to link an image.
* [#13883](http://dev.ckeditor.com/ticket/13883): Fixed: Copying a table using the context menu strips off styles.
* [#13872](http://dev.ckeditor.com/ticket/13872): Fixed: Cutting is possible in the [read-only](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) mode.
* [#12848](http://dev.ckeditor.com/ticket/12848): [Blink] Fixed: Opening the [Find and Replace](http://ckeditor.com/addon/find) dialog window in the [read-only](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) mode throws an exception.
* [#13879](http://dev.ckeditor.com/ticket/13879): Fixed: It is not possible to prevent the [`editor.drop`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-drop) event.
* [#13361](http://dev.ckeditor.com/ticket/13361): Fixed: Skin images fail when the site path includes parentheses because the `background-image` path needs single quotes around the URL value.
* [#13771](http://dev.ckeditor.com/ticket/13771): Fixed: The `contents.css` style is not used if the [IFrame Editing Area](http://ckeditor.com/addon/wysiwygarea) plugin is missing.
* [#13782](http://dev.ckeditor.com/ticket/13782): Fixed: Unclear log messages.
* [#13919](http://dev.ckeditor.com/ticket/13919): [Edge] Fixed: Browser window crashes when accessing the `isContentEditable` property of an `<input>` DOM element.
Other Changes:
* [#13859](http://dev.ckeditor.com/ticket/13859): Test cases created with `bender.tools.createTestsForEditors` will also receive editor bot as a second parameter.
## CKEditor 4.5.4
New Features:
* [#13632](http://dev.ckeditor.com/ticket/13632): Introduce error logging mechanism.
* [#13730](http://dev.ckeditor.com/ticket/13730): Switch to the new error logging mechanism.
Fixed Issues:
* [#9856](http://dev.ckeditor.com/ticket/9856): Fixed: Cannot use the native context menu together with the [Div Editing Area](http://ckeditor.com/addon/divarea) plugin. Thanks to [Mark Wade](https://github.com/mark-wade)!
* [#12733](http://dev.ckeditor.com/ticket/12733): [IE9+] Fixed: Radio button `onChange` does not work. Thanks to [Iliya Kostadinov](https://github.com/iliyakostadinov)!
* [#13142](http://dev.ckeditor.com/ticket/13142): [Edge] Fixed: *Ctrl+A* and then *Backspace* result in an empty `<div>` element.
* [#13599](http://dev.ckeditor.com/ticket/13599): Fixed: Cross-editor drag and drop of an inline widget results in error/artifacts.
* [#13640](http://dev.ckeditor.com/ticket/13640): [IE] Fixed: Dropping a widget outside the `<body>` element is not handled correctly.
* [#13533](http://dev.ckeditor.com/ticket/13533): Fixed: No progress during upload.
* [#13680](http://dev.ckeditor.com/ticket/13680): Fixed: The parser should allow the `<h1-6>` element to be a child of the `<summary>` element.
* [#11724](http://dev.ckeditor.com/ticket/11724): [Touch devices] Fixed: Drop-downs often hide right after opening them.
* [#13690](http://dev.ckeditor.com/ticket/13690): Fixed: Copying content from IE to Chrome adds an extra paragraph.
* [#13284](http://dev.ckeditor.com/ticket/13284): Fixed: Cannot drag and drop a widget if the text caret is placed just after the widget instance.
* [#13516](http://dev.ckeditor.com/ticket/13516): Fixed: CKEditor removes empty HTML5 anchors without the `name` attribute.
* [#13765](http://dev.ckeditor.com/ticket/13765): [Safari 9] Fixed: Problems with rendering samples.
Other Changes:
* [#11725](http://dev.ckeditor.com/ticket/11725): Marked [`CKEDITOR.env.mobile`](http://docs.ckeditor.com/#!/api/CKEDITOR.env-property-mobile) as deprecated. The reason is that it is no longer clear what "mobile" means.
* [#13737](http://dev.ckeditor.com/ticket/13737): Upgraded [Bender.js](https://github.com/benderjs/benderjs) to 0.4.1.
## CKEditor 4.5.3
New Features:
* [#13501](http://dev.ckeditor.com/ticket/13501): Added the [`config.fileTools_defaultFileName`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-fileTools_defaultFileName) option to allow setting a default file name for paste uploads.
* [#13603](http://dev.ckeditor.com/ticket/13603): Added support for uploading dropped BMP images.
Fixed Issues:
* [#13590](http://dev.ckeditor.com/ticket/13590): Fixed: Various issues related to the [Paste from Word](http://ckeditor.com/addon/pastefromword) feature. Fixes also:
* [#11215](http://dev.ckeditor.com/ticket/11215),
* [#8780](http://dev.ckeditor.com/ticket/8780),
* [#12762](http://dev.ckeditor.com/ticket/12762).
* [#13386](http://dev.ckeditor.com/ticket/13386): [Edge] Fixed: Issues with selecting and editing images.
* [#13568](http://dev.ckeditor.com/ticket/13568): Fixed: The [`editor.getSelectedHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml) method returns invalid results for entire content selection.
* [#13453](http://dev.ckeditor.com/ticket/13453): Fixed: Drag&drop of entire editor content throws an error.
* [#13465](http://dev.ckeditor.com/ticket/13465): Fixed: Error is thrown and the widget is lost on drag&drop if it is the only content of the editor.
* [#13414](http://dev.ckeditor.com/ticket/13414): Fixed: Content auto paragraphing in a nested editable despite editor configuration.
* [#13429](http://dev.ckeditor.com/ticket/13429): Fixed: Incorrect selection after content insertion by the [Auto Embed](http://ckeditor.com/addon/autoembed) plugin.
* [#13388](http://dev.ckeditor.com/ticket/13388): Fixed: [Table Resize](http://ckeditor.com/addon/tableresize) integration with [Undo](http://ckeditor.com/addon/undo) is broken.
Other Changes:
* [#13637](https://dev.ckeditor.com/ticket/13637): Several icons were refactored.
* Updated [Bender.js](https://github.com/benderjs/benderjs) to 0.3.0 and introduced the ability to run tests via HTTPs ([#13265](https://dev.ckeditor.com/ticket/13265)).
## CKEditor 4.5.2
Fixed Issues:
* [#13609](http://dev.ckeditor.com/ticket/13609): [Edge] Fixed: The browser crashes when switching to the source mode. Thanks to [Andrew Williams and Mark Smeed](http://webxsolution.com/)!
* [PR#201](https://github.com/ckeditor/ckeditor-dev/pull/201): Fixed: Buttons in the toolbar configurator cause form submission. Thanks to [colemanw](https://github.com/colemanw)!
* [#13422](http://dev.ckeditor.com/ticket/13422): Fixed: A monospaced font should be used in the `<textarea>` element storing editor configuration in the toolbar configurator.
* [#13494](http://dev.ckeditor.com/ticket/13494): Fixed: Error thrown in the toolbar configurator if plugin requirements are not met.
* [#13409](http://dev.ckeditor.com/ticket/13409): Fixed: List elements incorrectly merged when pressing *Backspace* or *Delete*.
* [#13434](http://dev.ckeditor.com/ticket/13434): Fixed: Dialog state indicator broken in Right–To–Left environments.
* [#13460](http://dev.ckeditor.com/ticket/13460): [IE8] Fixed: Copying inline widgets is broken when [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_acf) is disabled.
* [#13495](http://dev.ckeditor.com/ticket/13495): [Firefox, IE] Fixed: Text is not word-wrapped in the Paste dialog window.
* [#13528](http://dev.ckeditor.com/ticket/13528): [Firefox@Windows] Fixed: Content copied from Microsoft Word and other external applications is pasted as a plain text. Removed the `CKEDITOR.plugins.clipboard.isHtmlInExternalDataTransfer` property as the check must be dynamic.
* [#13583](http://dev.ckeditor.com/ticket/13583): Fixed: [`DataTransfer.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.clipboard.dataTransfer-method-getData) should work consistently in all browsers and should not strip valuable content. Fixed pasting tables from Microsoft Excel on Chrome.
* [#13468](http://dev.ckeditor.com/ticket/13468): [IE] Fixed: Binding drag&drop `dataTransfer` does not work if `text` data was set in the meantime.
* [#13451](http://dev.ckeditor.com/ticket/13451): [IE8-9] Fixed: One drag&drop operation may affect following ones.
* [#13184](http://dev.ckeditor.com/ticket/13184): Fixed: Web page reloaded after a drop on editor UI.
* [#13129](http://dev.ckeditor.com/ticket/13129) Fixed: Block widget blurred after a drop followed by an undo.
* [#13397](http://dev.ckeditor.com/ticket/13397): Fixed: Drag&drop of a widget inside its nested widget crashes the editor.
* [#13385](http://dev.ckeditor.com/ticket/13385): Fixed: [`editor.getSnapshot()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSnapshot) may return a non-string value.
* [#13419](http://dev.ckeditor.com/ticket/13419): Fixed: The [Auto Link](http://ckeditor.com/addon/autolink) plugin does not encode double quotes in URLs.
* [#13420](http://dev.ckeditor.com/ticket/13420): Fixed: The [Auto Embed](http://ckeditor.com/addon/autoembed) plugin ignores encoded characters in URL parameters.
* [#13410](http://dev.ckeditor.com/ticket/13410): Fixed: Error thrown in the [Auto Embed](http://ckeditor.com/addon/autoembed) plugin when undoing right after pasting a link.
* [#13566](http://dev.ckeditor.com/ticket/13566): Fixed: Suppressed notifications in the [Media Embed Base](http://ckeditor.com/addon/embedbase) plugin.
* [#11616](http://dev.ckeditor.com/ticket/11616): [Chrome] Fixed: Resizing the editor while it is not displayed breaks the editable. Fixes also [#9160](http://dev.ckeditor.com/ticket/9160) and [#9715](http://dev.ckeditor.com/ticket/9715).
* [#11376](http://dev.ckeditor.com/ticket/11376): [IE11] Fixed: Loss of text when pasting bulleted lists from Microsoft Word.
* [#13143](http://dev.ckeditor.com/ticket/13143): [Edge] Fixed: Focus lost when opening the panel.
* [#13387](http://dev.ckeditor.com/ticket/13387): [Edge] Fixed: "Permission denied" error thrown when loading the editor with developer tools open.
* [#13574](http://dev.ckeditor.com/ticket/13574): [Edge] Fixed: "Permission denied" error thrown when opening editor dialog windows.
* [#13441](http://dev.ckeditor.com/ticket/13441): [Edge] Fixed: The [Clipboard](http://ckeditor.com/addon/clipboard) plugin breaks the state of [Undo](http://ckeditor.com/addon/undo) commands after a paste.
* [#13554](http://dev.ckeditor.com/ticket/13554): [Edge] Fixed: Paste dialog's iframe does not receive focus on show.
* [#13440](http://dev.ckeditor.com/ticket/13440): [Edge] Fixed: Unable to paste a widget.
Other Changes:
* [#13421](http://dev.ckeditor.com/ticket/13421): UX improvements to notifications in the [Auto Embed](http://ckeditor.com/addon/autoembed) plugin.
## CKEditor 4.5.1
Fixed Issues:
* [#13486](http://dev.ckeditor.com/ticket/13486): Fixed: The [Upload Image](http://ckeditor.com/addon/uploadimage) plugin should log an error, not throw an error when upload URL is not set.
## CKEditor 4.5
New Features:
* [#13304](http://dev.ckeditor.com/ticket/13304): Added support for passing DOM elements to [`config.sharedSpaces`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-sharedSpaces). Thanks to [Undergrounder](https://github.com/Undergrounder)!
* [#13215](http://dev.ckeditor.com/ticket/13215): Added ability to cancel fetching a resource by the Embed plugins.
* [#13213](http://dev.ckeditor.com/ticket/13213): Added the [`dialog#setState()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dialog-method-setState) method and used it in the [Embed](http://ckeditor.com/addon/embed) dialog to indicate that a resource is being loaded.
* [#13337](http://dev.ckeditor.com/ticket/13337): Added the [`repository.onWidget()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-onWidget) method &mdash; a convenient way to listen to [widget](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget) events through the [repository](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository).
* [#13214](http://dev.ckeditor.com/ticket/13214): Added support for pasting links that convert into embeddable resources on the fly.
Fixed Issues:
* [#13334](http://dev.ckeditor.com/ticket/13334): Fixed: Error after nesting widgets and playing with undo/redo.
* [#13118](http://dev.ckeditor.com/ticket/13118): Fixed: The [`editor.getSelectedHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml) method throws an error when called in the source mode.
* [#13158](http://dev.ckeditor.com/ticket/13158): Fixed: Error after canceling a dialog when creating a widget.
* [#13197](http://dev.ckeditor.com/ticket/13197): Fixed: Linked inline [Enhanced Image](http://ckeditor.com/addon/image2) alignment class is not transferred to the widget wrapper.
* [#13199](http://dev.ckeditor.com/ticket/13199): Fixed: [Semantic Embed](http://ckeditor.com/addon/embedsemantic) does not support widget classes.
* [#13003](http://dev.ckeditor.com/ticket/13003): Fixed: Anchors are uploaded when moving them by drag and drop.
* [#13032](http://dev.ckeditor.com/ticket/13032): Fixed: When upload is done, notification update should be marked as important.
* [#13300](http://dev.ckeditor.com/ticket/13300): Fixed: The `internalCommit` argument in the [Image](http://ckeditor.com/addon/image) dialog seems to be never used.
* [#13036](http://dev.ckeditor.com/ticket/13036): Fixed: Notifications are moved 10px to the right.
* [#13280](http://dev.ckeditor.com/ticket/13280): [IE8] Fixed: Undo after inline widget drag&drop throws an error.
* [#13186](http://dev.ckeditor.com/ticket/13186): Fixed: Content dropped into a nested editable is not filtered by [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_acf).
* [#13140](http://dev.ckeditor.com/ticket/13140): Fixed: Error thrown when dropping a block widget right after itself.
* [#13176](http://dev.ckeditor.com/ticket/13176): [IE8] Fixed: Errors on drag&drop of embed widgets.
* [#13015](http://dev.ckeditor.com/ticket/13015): Fixed: Dropping an image file on [Enhanced Image](http://ckeditor.com/addon/image2) causes a page reload.
* [#13080](http://dev.ckeditor.com/ticket/13080): Fixed: Ugly notification shown when the response contains HTML content.
* [#13011](http://dev.ckeditor.com/ticket/13011): [IE8] Fixed: Anchors are duplicated on drag&drop in specific locations.
* [#13105](http://dev.ckeditor.com/ticket/13105): Fixed: Various issues related to [`CKEDITOR.tools.htmlEncode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-htmlEncode) and [`CKEDITOR.tools.htmlDecode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-htmlDecode) methods.
* [#11976](http://dev.ckeditor.com/ticket/11976): [Chrome] Fixed: Copy&paste and drag&drop lists from Microsoft Word.
* [#13128](http://dev.ckeditor.com/ticket/13128): Fixed: Various issues with cloning element IDs:
* Fixed the default behavior of [`range.cloneContents()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-cloneContents) and [`range.extractContents()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-extractContents) methods which now clone IDs similarly to their native counterparts.
* Added `cloneId` arguments to the above methods, [`range.splitBlock()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-splitBlock) and [`element.breakParent()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-breakParent). Mind the default values and special behavior in the `extractContents()` method!
* Fixed issues where IDs were lost on copy&paste and drag&drop.
* Toolbar configurators:
* [#13185](http://dev.ckeditor.com/ticket/13185): Fixed: Wrong position of the suggestion box if there is not enough space below the caret.
* [#13138](http://dev.ckeditor.com/ticket/13138): Fixed: The "Toggle empty elements" button label is unclear.
* [#13136](http://dev.ckeditor.com/ticket/13136): Fixed: Autocompleter is far too intrusive.
* [#13133](http://dev.ckeditor.com/ticket/13133): Fixed: Tab leaves the editor.
* [#13173](http://dev.ckeditor.com/ticket/13173): Fixed: [`config.removeButtons`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-removeButtons) is ignored by the advanced toolbar configurator.
Other Changes:
* [#13119](http://dev.ckeditor.com/ticket/13119): Improved compatibility of editor skins ([Moono](http://ckeditor.com/addon/moono) and [Kama](http://ckeditor.com/addon/kama)) with external web page style sheets.
* Toolbar configurators:
* [#13147](http://dev.ckeditor.com/ticket/13147): Added buttons to the sticky toolbar.
* [#13207](http://dev.ckeditor.com/ticket/13207): Used modal window to display toolbar configurator help.
* [#13316](http://dev.ckeditor.com/ticket/13316): Made [`CKEDITOR.env.isCompatible`](http://docs.ckeditor.com/#!/api/CKEDITOR.env-property-isCompatible) a blacklist rather than a whitelist. More about the change in the [Browser Compatibility](http://docs.ckeditor.com/#!/guide/dev_browsers) guide.
* [#13398](http://dev.ckeditor.com/ticket/13398): Renamed `CKEDITOR.fileTools.UploadsRepository` to [`CKEDITOR.fileTools.UploadRepository`](http://docs.ckeditor.com/#!/api/CKEDITOR.fileTools.uploadRepository) and changed all related properties.
* [#13279](http://dev.ckeditor.com/ticket/13279): Reviewed CSS vendor prefixes.
* [#13454](http://dev.ckeditor.com/ticket/13454): Removed unused `lang.image.alertUrl` token from the [Image](http://ckeditor.com/addon/image) plugin.
## CKEditor 4.5 Beta
New Features:
* Clipboard (copy&paste, drag&drop) and file uploading features and improvements ([#11437](http://dev.ckeditor.com/ticket/11437)).
* Major features:
* Support for dropping and pasting files into the editor was introduced. Through a set of new facades for native APIs it is now possible to easily intercept and process inserted files.
* [File upload tools](http://docs.ckeditor.com/#!/api/CKEDITOR.fileTools) were introduced in order to simplify controlling the loading, uploading and handling server response, properly handle [new upload configuration](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-uploadUrl) options, etc.
* [Upload Image](http://ckeditor.com/addon/uploadimage) widget was introduced to upload dropped images. A base class for the [upload widget](http://docs.ckeditor.com/#!/api/CKEDITOR.fileTools.uploadWidgetDefinition) was exposed, too, to make it simple to create new types of upload widgets which can handle any type of dropped file, show the upload progress and update the content when the process is done. It also handles editing and undo/redo operations when a file is being uploaded and integrates with the [notification aggregator](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.notificationAggregator) to show progress and success or error.
* All drag and drop operations were integrated with the editor. All dropped content is passed through the [`editor#paste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-paste) event and a set of new editor events was introduced &mdash; [`dragstart`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-dragstart), [`drop`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-drop), [`dragend`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-dragend).
* The [Data Transfer](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.clipboard.dataTransfer) facade was introduced to unify access to data in various types and files. [Data Transfer](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.clipboard.dataTransfer) is now always available in the [`editor#paste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-paste) event.
* Switched from the pastebin to using the native clipboard access whenever possible. This solved many issues related to pastebin such as unnecessary scrolling or data loss. Additionally, on copy and cut from the editor the clipboard data is set. Therefore, on paste the editor has access to clean data, undisturbed by the browsers.
* Drag and drop of inline and block widgets was integrated with the standard clipboard APIs. By listening to drag events you will thus be notified about widgets, too. This opens a possibility to filter pasted and dropped widgets.
* The [`editor#paste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-paste) event can have the `range` parameter so it is possible to change the paste position in the listener or paste in the not selectable position. Also the [`editor.insertHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertHtml) method now accepts `range` as an additional parameter.
* [#11621](http://dev.ckeditor.com/ticket/11621): A configurable [paste filter](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFilter) was introduced. The filter is by default turned to `'semantic-content'` on Webkit and Blink for all pasted content coming from external sources because of the low quality of HTML that these engines put into the clipboard. Internal and cross-editor paste is safe due to the change explained in the previous point.
* Other changes and related fixes:
* [#12095](http://dev.ckeditor.com/ticket/12095): On drag and copy of widgets [the same method](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml) is used to get selected HTML as in the normal case. Thanks to that styles applied to inline widgets are not lost.
* [#11219](http://dev.ckeditor.com/ticket/11219): Fixed: Dragging a [captioned image](http://ckeditor.com/addon/image2) does not fire the [`editor#paste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-paste) event.
* [#9554](http://dev.ckeditor.com/ticket/9554): [Webkit Mac] Fixed: Editor scrolls on paste.
* [#9898](http://dev.ckeditor.com/ticket/9898): [Webkit&Divarea] Fixed: Pasting causes undesirable scrolling.
* [#11993](http://dev.ckeditor.com/ticket/11993): [Chrome] Fixed: Pasting content scrolls the document.
* [#12613](http://dev.ckeditor.com/ticket/12613): Show the user that they can not drop on editor UI (toolbar, bottom bar).
* [#12851](http://dev.ckeditor.com/ticket/12851): [Blink/Webkit] Fixed: Formatting disappears when pasting content into cells.
* [#12914](http://dev.ckeditor.com/ticket/12914): Fixed: Copy/Paste of table broken in `div`-based editor.
* Browser support.<br>Browser support for related features varies significantly (see http://caniuse.com/clipboard).
* File APIs needed to operate and file upload is not supported in Internet Explorer 9 and below.
* Only Chrome and Safari on Mac OS support setting custom data items in the clipboard, so currently it is possible to recognize the origin of the copied content in these browsers only. All drag and drop operations can be identified thanks to the new Data Transfer facade.
* No Internet Explorer browser supports the standard clipboard API which results in small glitches like where only plain text can be dropped from outside the editor. Thanks to the new Data Transfer facade, internal and cross-editor drag and drop supports the full range of data.
* Direct access to clipboard could only be implemented in Chrome, Safari on Mac OS, Opera and Firefox. In other browsers the pastebin must still be used.
* [#12875](http://dev.ckeditor.com/ticket/12875): Samples and toolbar configuration tools.
* The old set of samples shipped with every CKEditor package was replaced with a shiny new single-page sample. This change concluded a long term plan which started from introducing the [CKEditor SDK](http://sdk.ckeditor.com/) and [CKEditor Functionality Overview](http://docs.ckeditor.com/#!/guide/dev_features) section in the documentation which essentially redefined the old samples.
* Toolbar configurators with live previews were introduced. They will be shipped with every CKEditor package and are meant to help in configuring toolbar layouts.
* [#10925](http://dev.ckeditor.com/ticket/10925): The [Media Embed](http://ckeditor.com/addon/embed) and [Semantic Media Embed](http://ckeditor.com/addon/embedsemantic) plugins were introduced. Read more about the new features in the [Embedding Content](http://docs.ckeditor.com/#!/guide/dev_media_embed) article.
* [#10931](http://dev.ckeditor.com/ticket/10931): Added support for nesting widgets. It is now possible to insert one widget into another widget's nested editable. Note that unless nested editable's [allowed content](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.nestedEditable.definition-property-allowedContent) is defined precisely, starting from CKEditor 4.5 some widget buttons may become enabled. This feature is not supported in IE8. Included issues:
* [#12018](http://dev.ckeditor.com/ticket/12018): Fixed and reviewed: Nested widgets garbage collection.
* [#12024](http://dev.ckeditor.com/ticket/12024): [Firefox] Fixed: Outline is extended to the left by unpositioned drag handlers.
* [#12006](http://dev.ckeditor.com/ticket/12006): Fixed: Drag and drop of nested block widgets.
* [#12008](http://dev.ckeditor.com/ticket/12008): Fixed various cases of inserting a single non-editable element using the [`editor.insertHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertHtml) method. Fixes pasting a widget with a nested editable inside another widget's nested editable.
* Notification system:
* [#11580](http://dev.ckeditor.com/ticket/11580): Introduced the [notification system](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.notification).
* [#12810](http://dev.ckeditor.com/ticket/12810): Introduced a [notification aggregator](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.notificationAggregator) for the [notification system](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.notification) which simplifies displaying progress of many concurrent tasks.
* [#11636](http://dev.ckeditor.com/ticket/11636): Introduced new, UX-focused, methods for getting selected HTML and deleting it &mdash; [`editor.getSelectedHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml) and [`editor.deleteSelectedHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml).
* [#12416](http://dev.ckeditor.com/ticket/12416): Added the [`widget.definition.upcastPriority`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-upcastPriority) property which gives more control over widget upcasting order to the widget author.
* [#12036](http://dev.ckeditor.com/ticket/12036): Initialize the editor in [read-only](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) mode when the `<textarea>` element has a `readonly` attribute.
* [#11905](http://dev.ckeditor.com/ticket/11905): The [`resize` event](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-resize) passes the current dimensions in its data.
* [#12126](http://dev.ckeditor.com/ticket/12126): Introduced [`config.image_prefillDimensions`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image_prefillDimensions) and [`config.image2_prefillDimensions`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image2_prefillDimensions) to make pre-filling `width` and `height` configurable for the [Enhanced Image](http://ckeditor.com/addon/image2).
* [#12746](http://dev.ckeditor.com/ticket/12746): Added a new configuration option to hide the [Enhanced Image](http://ckeditor.com/addon/image2) resizer.
* [#12150](http://dev.ckeditor.com/ticket/12150): Exposed the [`getNestedEditable()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-static-method-getNestedEditable) and `is*` [widget helper](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget) functions (see the static methods).
* [#12448](http://dev.ckeditor.com/ticket/12448): Introduced the [`editable.insertHtmlIntoRange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertHtmlIntoRange) method.
* [#12143](http://dev.ckeditor.com/ticket/12143): Added the [`config.floatSpacePreferRight`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-floatSpacePreferRight) configuration option that switches the alignment of the floating toolbar. Thanks to [InvisibleBacon](http://github.com/InvisibleBacon)!
* [#10986](http://dev.ckeditor.com/ticket/10986): Added support for changing dialog input and textarea text directions by using the *Shift+Alt+Home/End* keystrokes. The direction is stored in the value of the input by prepending the [`\u202A`](http://unicode.org/cldr/utility/character.jsp?a=202A) or [`\u202B`](http://unicode.org/cldr/utility/character.jsp?a=202B) marker to it. Read more in the [documentation](http://docs.ckeditor.com/#!/api/CKEDITOR.dialog.definition.textInput-property-bidi). Thanks to [edithkk](https://github.com/edithkk)!
* [#12770](http://dev.ckeditor.com/ticket/12770): Added support for passing [widget](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget)'s startup data as a widget command's argument. Thanks to [Rebrov Boris](https://github.com/zipp3r) and [Tieme van Veen](https://github.com/tiemevanveen)!
* [#11583](http://dev.ckeditor.com/ticket/11583): Added support for the HTML5 `required` attribute in various form elements. Thanks to [Steven Busse](https://github.com/sbusse)!
Changes:
* [#12858](http://dev.ckeditor.com/ticket/12858): Basic [Spartan](http://blogs.windows.com/bloggingwindows/2015/03/30/introducing-project-spartan-the-new-browser-built-for-windows-10/) browser compatibility. Full compatibility will be introduced later, because at the moment Spartan is still too unstable to be used for tests and we see many changes from version to version.
* [#12948](http://dev.ckeditor.com/ticket/12948): The [`config.mathJaxLibrary`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-mathJaxLib) option does not default to the MathJax CDN any more. It needs to be configured to enable the [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin now.
* [#13069](http://dev.ckeditor.com/ticket/13069): Fixed inconsistencies between [`editable.insertHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElement) and [`editable.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElement) when the `range` parameter is used. Now, the `editor.insertElement()` method works on a higher level, which means that it saves undo snapshots and sets the selection after insertion. Use the [`editable.insertElementIntoRange()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElementIntoRange) method directly for the pre 4.5 behavior of `editable.insertElement()`.
* [#12870](http://dev.ckeditor.com/ticket/12870): Use [`editor.showNotification()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-showNotification) instead of `alert()` directly whenever possible. When the [Notification plugin](http://ckeditor.com/addon/notification) is loaded, the notification system is used automatically. Otherwise, the native `alert()` is displayed.
* [#8024](http://dev.ckeditor.com/ticket/8024): Swapped behavior of the Split Cell Vertically and Horizontally features of the [Table Tools](http://ckeditor.com/addon/tabletools) plugin to be more intuitive. Thanks to [kevinisagit](https://github.com/kevinisagit)!
* [#10903](http://dev.ckeditor.com/ticket/10903): Performance improvements for the [`dom.element.addClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-addClass), [`dom.element.removeClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-removeClass) and [`dom.element.hasClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-hasClass) methods. Note: The previous implementation allowed passing multiple classes to `addClass()` although it was only a side effect of that implementation. The new implementation does not allow this.
* [#11856](http://dev.ckeditor.com/ticket/11856): The jQuery adapter throws a meaningful error if CKEditor or jQuery are not loaded.
Fixed issues:
* [#11586](http://dev.ckeditor.com/ticket/11586): Fixed: [`range.cloneContents()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-cloneContents) should not change the DOM in order not to affect selection.
* [#12148](http://dev.ckeditor.com/ticket/12148): Fixed: [`dom.element.getChild()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-getChild) should not modify a passed array.
* [#12503](http://dev.ckeditor.com/ticket/12503): [Blink/Webkit] Fixed: Incorrect result of Select All and *Backspace* or *Delete*.
* [#13001](http://dev.ckeditor.com/ticket/13001): [Firefox] Fixed: The `<br />` filler is placed in the wrong position by the [`range.fixBlock()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-fixBlock) method due to quirky Firefox behavior.
* [#13101](http://dev.ckeditor.com/ticket/13101): [IE8] Fixed: Colons are prepended to HTML5 element names when cloning them.
## CKEditor 4.4.8
**Security Updates:**
* Fixed XSS vulnerability in the HTML parser reported by [Dheeraj Joshi](https://twitter.com/dheerajhere) and [Prem Kumar](https://twitter.com/iAmPr3m).
Issue summary: It was possible to execute XSS inside CKEditor after persuading the victim to: (i) switch CKEditor to source mode, then (ii) paste a specially crafted HTML code, prepared by the attacker, into the opened CKEditor source area, and (iii) switch back to WYSIWYG mode.
**An upgrade is highly recommended!**
Fixed Issues:
* [#12899](http://dev.ckeditor.com/ticket/12899): Fixed: Corrected wrong tag ending for horizontal box definition in the [Dialog User Interface](http://ckeditor.com/addon/dialogui) plugin. Thanks to [mizafish](https://github.com/mizafish)!
* [#13254](http://dev.ckeditor.com/ticket/13254): Fixed: Cannot outdent block after indent when using the [Div Editing Area](http://ckeditor.com/addon/divarea) plugin. Thanks to [Jonathan Cottrill](https://github.com/jcttrll)!
* [#13268](http://dev.ckeditor.com/ticket/13268): Fixed: Documentation for [`CKEDITOR.dom.text`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.text) is incorrect. Thanks to [Ben Kiefer](https://github.com/benkiefer)!
* [#12739](http://dev.ckeditor.com/ticket/12739): Fixed: Link loses inline styles when edited without the [Advanced Tab for Dialogs](http://ckeditor.com/addon/dialogadvtab) plugin. Thanks to [Віталій Крутько](https://github.com/asmforce)!
* [#13292](http://dev.ckeditor.com/ticket/13292): Fixed: Protection pattern does not work in attribute in self-closing elements with no space before `/>`. Thanks to [Віталій Крутько](https://github.com/asmforce)!
* [PR#192](https://github.com/ckeditor/ckeditor-dev/pull/192): Fixed: Variable name typo in the [Dialog User Interface](http://ckeditor.com/addon/dialogui) plugin which caused [`CKEDITOR.ui.dialog.radio`](http://docs.ckeditor.com/#!/api/CKEDITOR.ui.dialog.radio) validation to not work. Thanks to [Florian Ludwig](https://github.com/FlorianLudwig)!
* [#13232](http://dev.ckeditor.com/ticket/13232): [Safari] Fixed: The [`element.appendText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-appendText) method does not work properly for empty elements.
* [#13233](http://dev.ckeditor.com/ticket/13233): Fixed: [HTMLDataProcessor](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlDataProcessor) can process `foo:href` attributes.
* [#12796](http://dev.ckeditor.com/ticket/12796): Fixed: The [Indent List](http://ckeditor.com/addon/indentlist) plugin unwraps parent `<li>` elements. Thanks to [Andrew Stucki](https://github.com/andrewstucki)!
* [#12885](http://dev.ckeditor.com/ticket/12885): Added missing [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) parameter documentation.
* [#11982](http://dev.ckeditor.com/ticket/11982): Fixed: Bullet added in a wrong position after the *Enter* key is pressed in a nested list.
* [#13027](http://dev.ckeditor.com/ticket/13027): Fixed: Keyboard navigation in dialog windows with multiple tabs not following IBM CI 162 instructions or [ARIA Authoring Practices](http://www.w3.org/TR/2013/WD-wai-aria-practices-20130307/#tabpanel).
* [#12256](http://dev.ckeditor.com/ticket/12256): Fixed: Basic styles classes are lost when pasting from Microsoft Word if [basic styles](http://ckeditor.com/addon/basicstyles) were configured to use classes.
* [#12729](http://dev.ckeditor.com/ticket/12729): Fixed: Incorrect structure created when merging a block into a list item on *Backspace* and *Delete*.
* [#13031](http://dev.ckeditor.com/ticket/13031): [Firefox] Fixed: No more line breaks in source view since Firefox 36.
* [#13131](http://dev.ckeditor.com/ticket/13131): Fixed: The [Code Snippet](http://ckeditor.com/addon/codesnippet) plugin cannot be used without the [IFrame Editing Area](http://ckeditor.com/addon/wysiwygarea) plugin.
* [#9086](http://dev.ckeditor.com/ticket/9086): Fixed: Invalid ARIA property used on paste area `<iframe>`.
* [#13164](http://dev.ckeditor.com/ticket/13164): Fixed: Error when inserting a hidden field.
* [#13155](http://dev.ckeditor.com/ticket/13155): Fixed: Incorrect [Line Utilities](http://ckeditor.com/addon/lineutils) positioning when `<body>` has a margin.
* [#13351](http://dev.ckeditor.com/ticket/13351): Fixed: Link lost when editing a linked image with the Link tab disabled. This also fixed a bug when inserting an image into a fully selected link would throw an error ([#12847](https://dev.ckeditor.com/ticket/12847)).
* [#13344](http://dev.ckeditor.com/ticket/13344): [WebKit/Blink] Fixed: It is possible to remove or change editor content in [read-only mode](http://docs.ckeditor.com/#!/guide/dev_readonly).
Other Changes:
* [#12844](http://dev.ckeditor.com/ticket/12844) and [#13103](http://dev.ckeditor.com/ticket/13103): Upgraded the [testing environment](http://docs.ckeditor.com/#!/guide/dev_tests) to [Bender.js](https://github.com/benderjs/benderjs) `0.2.3`.
* [#12930](http://dev.ckeditor.com/ticket/12930): Because of licensing issues, `truncated-mathjax/` is now removed from the `tests/` directory. Now `bender.config.mathJaxLibPath` must be configured manually in order to run [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin tests.
* [#13266](http://dev.ckeditor.com/ticket/13266): Added more shades of gray in the [Color Dialog](http://ckeditor.com/addon/colordialog) window. Thanks to [mizafish](https://github.com/mizafish)!
## CKEditor 4.4.7
Fixed Issues:
......@@ -11,7 +409,7 @@ Fixed Issues:
* [#12812](http://dev.ckeditor.com/ticket/12812): Fixed: An uncaught security exception is thrown when [Line Utilities](http://ckeditor.com/addon/lineutils) are used in an inline editor loaded in a cross-domain `iframe`. Thanks to [Vitaliy Zurian](https://github.com/thecatontheflat)!
* [#12735](http://dev.ckeditor.com/ticket/12735): Fixed: [`config.fillEmptyBlocks`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-fillEmptyBlocks) should only apply when outputting data.
* [#10032](http://dev.ckeditor.com/ticket/10032): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) filter is executed for every paste after using the button.
* [#12597](http://dev.ckeditor.com/ticket/12597): [Blink/Webkit] Fixed: Multi-byte Japanese characters entry not working properly after *Shift+Enter*.
* [#12597](http://dev.ckeditor.com/ticket/12597): [Blink/WebKit] Fixed: Multi-byte Japanese characters entry not working properly after *Shift+Enter*.
* [#12387](http://dev.ckeditor.com/ticket/12387): Fixed: An error is thrown if a skin does not have the [`chameleon`](http://docs.ckeditor.com/#!/api/CKEDITOR.skin-method-chameleon) property defined and [`config.uiColor`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-uiColor) is defined.
* [#12747](http://dev.ckeditor.com/ticket/12747): [IE8-10] Fixed: Opening a drop-down for a specific selection when the editor is maximized results in incorrect drop-down panel position.
* [#12850](http://dev.ckeditor.com/ticket/12850): [IEQM] Fixed: An error is thrown after focusing the editor.
......@@ -44,7 +442,7 @@ Fixed Issues:
* [#12300](http://dev.ckeditor.com/ticket/12300): Fixed: The [`editor.change`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event fired on first navigation key press after typing.
* [#12141](http://dev.ckeditor.com/ticket/12141): Fixed: List items are lost when indenting a list item with content wrapped with a block element.
* [#12515](http://dev.ckeditor.com/ticket/12515): Fixed: Cursor is in the wrong position when undoing after adding an image and typing some text.
* [#12484](http://dev.ckeditor.com/ticket/12484): [Blink/Webkit] Fixed: DOM is changed outside the editor area in a certain case.
* [#12484](http://dev.ckeditor.com/ticket/12484): [Blink/WebKit] Fixed: DOM is changed outside the editor area in a certain case.
* [#12688](http://dev.ckeditor.com/ticket/12688): Improved the tests of the [styles system](http://docs.ckeditor.com/#!/api/CKEDITOR.style) and fixed two minor issues.
* [#12403](http://dev.ckeditor.com/ticket/12403): Fixed: Changing the [font](http://ckeditor.com/addon/font) style should not lead to nesting it in the previous style element.
* [#12609](http://dev.ckeditor.com/ticket/12609): Fixed: Incorrect `config.magicline_putEverywhere` name used for a [Magic Line](http://ckeditor.com/addon/magicline) all-encompassing [`config.magicline_everywhere`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-magicline_everywhere) configuration option.
......@@ -176,8 +574,8 @@ New Features:
Fixed Issues:
* [#11861](http://dev.ckeditor.com/ticket/11861): [Webkit/Blink] Fixed: Span elements created while joining adjacent elements. **Note:** This patch only covers cases when *Backspace* or *Delete* is pressed on a collapsed (empty) selection. The remaining case, with a non-empty selection, will be fixed in the next release.
* [#10714](http://dev.ckeditor.com/ticket/10714): [iOS] Fixed: Selection and drop-downs are broken if a touch event listener is used due to a [Webkit bug](https://bugs.webkit.org/show_bug.cgi?id=128924). Thanks to [Arty Gus](https://github.com/artygus)!
* [#11861](http://dev.ckeditor.com/ticket/11861): [WebKit/Blink] Fixed: Span elements created while joining adjacent elements. **Note:** This patch only covers cases when *Backspace* or *Delete* is pressed on a collapsed (empty) selection. The remaining case, with a non-empty selection, will be fixed in the next release.
* [#10714](http://dev.ckeditor.com/ticket/10714): [iOS] Fixed: Selection and drop-downs are broken if a touch event listener is used due to a [WebKit bug](https://bugs.webkit.org/show_bug.cgi?id=128924). Thanks to [Arty Gus](https://github.com/artygus)!
* [#11911](http://dev.ckeditor.com/ticket/11911): Fixed setting the `dir` attribute for a preloaded language in [CKEDITOR.lang](http://docs.ckeditor.com/#!/api/CKEDITOR.lang). Thanks to [Akash Mohapatra](https://github.com/akashmohapatra)!
* [#11926](http://dev.ckeditor.com/ticket/11926): Fixed: [Code Snippet](http://ckeditor.com/addon/codesnippet) does not decode HTML entities when loading code from the `<code>` element.
* [#11223](http://dev.ckeditor.com/ticket/11223): Fixed: Issue when [Protected Source](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-protectedSource) was not working in the `<title>` element.
......@@ -190,7 +588,7 @@ Fixed Issues:
* [#11813](http://dev.ckeditor.com/ticket/11813): Fixed: Link lost while pasting a captioned image and restoring an undo snapshot ([Enhanced Image](http://ckeditor.com/addon/image2)).
* [#11814](http://dev.ckeditor.com/ticket/11814): Fixed: _Link_ and _Unlink_ entries persistently displayed in the [Enhanced Image](http://ckeditor.com/addon/image2) context menu.
* [#11839](http://dev.ckeditor.com/ticket/11839): [IE9] Fixed: The caret jumps out of the editable area when resizing the editor in the source mode.
* [#11822](http://dev.ckeditor.com/ticket/11822): [Webkit] Fixed: Editing anchors by double-click is broken in some cases.
* [#11822](http://dev.ckeditor.com/ticket/11822): [WebKit] Fixed: Editing anchors by double-click is broken in some cases.
* [#11823](http://dev.ckeditor.com/ticket/11823): [IE8] Fixed: [Table Resize](http://ckeditor.com/addon/tableresize) throws an error over scrollbar.
* [#11788](http://dev.ckeditor.com/ticket/11788): Fixed: It is not possible to change the language back to _Not set_ in the [Code Snippet](http://ckeditor.com/addon/codesnippet) dialog window.
* [#11788](http://dev.ckeditor.com/ticket/11788): Fixed: [Filter](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter) rules are not applied inside elements with the `contenteditable` attribute set to `true`.
......@@ -283,7 +681,7 @@ Fixed Issues:
Fixed Issues:
* [#11500](http://dev.ckeditor.com/ticket/11500): [Webkit/Blink] Fixed: Selection lost when setting data in another inline editor. Additionally, [`selection.removeAllRanges()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-removeAllRanges) is now scoped to selection's [root](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-property-root).
* [#11500](http://dev.ckeditor.com/ticket/11500): [WebKit/Blink] Fixed: Selection lost when setting data in another inline editor. Additionally, [`selection.removeAllRanges()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-removeAllRanges) is now scoped to selection's [root](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-property-root).
* [#11104](http://dev.ckeditor.com/ticket/11104): [IE] Fixed: Various issues with scrolling and selection when focusing widgets.
* [#11487](http://dev.ckeditor.com/ticket/11487): Moving mouse over the [Enhanced Image](http://ckeditor.com/addon/image2) widget will no longer change the value returned by the [`editor.checkDirty()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty) method.
* [#8673](http://dev.ckeditor.com/ticket/8673): [WebKit] Fixed: Cannot select and remove the [Page Break](http://ckeditor.com/addon/pagebreak).
......