diff --git a/.gitignore b/.gitignore
index d600338f..3904ba6d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,5 @@
.idea
vendor/
-composer.lock
composer.phar
config.php
.DS_Store
diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php
index b8979452..f62fd758 100644
--- a/PHPCI/Builder.php
+++ b/PHPCI/Builder.php
@@ -73,7 +73,12 @@ class Builder
* @var array
*/
protected $config;
-
+
+ /**
+ * @var string
+ */
+ protected $lastOutput;
+
/**
* An array of key => value pairs that will be used for
* interpolation and environment variables
@@ -83,6 +88,11 @@ class Builder
*/
protected $interpolation_vars = array();
+ /**
+ * @var \PHPCI\Store\BuildStore
+ */
+ protected $store;
+
/**
* Set up the builder.
* @param \PHPCI\Model\Build
@@ -214,17 +224,24 @@ class Builder
$this->log('Executing: ' . $command, ' ');
- $output = '';
$status = 0;
- exec($command, $output, $status);
+ exec($command, $this->lastOutput, $status);
- if (!empty($output) && ($this->verbose || $status != 0)) {
- $this->log($output, ' ');
+ if (!empty($this->lastOutput) && ($this->verbose || $status != 0)) {
+ $this->log($this->lastOutput, ' ');
}
return ($status == 0) ? true : false;
}
+ /**
+ * Returns the output from the last command run.
+ */
+ public function getLastOutput()
+ {
+ return implode(PHP_EOL, $this->lastOutput);
+ }
+
/**
* Add an entry to the build log.
* @param string|string[]
@@ -433,4 +450,13 @@ class Builder
$this->log('Removing build.');
shell_exec(sprintf('rm -Rf "%s"', $this->buildPath));
}
+
+ /**
+ * Store build meta data
+ */
+ public function storeBuildMeta($key, $value)
+ {
+ $value = json_encode($value);
+ $this->store->setMeta($this->build->getProjectId(), $this->build->getId(), $key, $value);
+ }
}
diff --git a/PHPCI/Controller/BuildController.php b/PHPCI/Controller/BuildController.php
index b907b9bc..0dc927b7 100644
--- a/PHPCI/Controller/BuildController.php
+++ b/PHPCI/Controller/BuildController.php
@@ -31,10 +31,28 @@ class BuildController extends \PHPCI\Controller
public function view($buildId)
{
$build = $this->_buildStore->getById($buildId);
+ $this->view->plugins = $this->getUiPlugins();
$this->view->build = $build;
$this->view->data = $this->getBuildData($buildId);
}
+ protected function getUiPlugins()
+ {
+ $rtn = array();
+ $path = APPLICATION_PATH . 'public/assets/js/build-plugins/';
+ $dir = opendir($path);
+
+ while ($item = readdir($dir)) {
+ if (substr($item, 0, 1) == '.' || substr($item, -3) != '.js') {
+ continue;
+ }
+
+ $rtn[] = $item;
+ }
+
+ return $rtn;
+ }
+
/**
* AJAX call to get build data:
*/
@@ -43,6 +61,23 @@ class BuildController extends \PHPCI\Controller
die($this->getBuildData($buildId));
}
+ /**
+ * AJAX call to get build meta:
+ */
+ public function meta($buildId)
+ {
+ $build = $this->_buildStore->getById($buildId);
+ $key = $this->getParam('key', null);
+ $numBuilds = $this->getParam('num_builds', 1);
+ $data = null;
+
+ if ($key && $build) {
+ $data = $this->_buildStore->getMeta($key, $build->getProjectId(), $buildId, $numBuilds);
+ }
+
+ die(json_encode($data));
+ }
+
/**
* Get build data from database and json encode it:
*/
diff --git a/PHPCI/Model/Base/BuildBase.php b/PHPCI/Model/Base/BuildBase.php
index b681c110..33f3d406 100644
--- a/PHPCI/Model/Base/BuildBase.php
+++ b/PHPCI/Model/Base/BuildBase.php
@@ -579,4 +579,16 @@ class BuildBase extends Model
{
return $this->setProjectId($value->getId());
}
+
+ /**
+ * Get BuildMeta models by BuildId for this Build.
+ *
+ * @uses \PHPCI\Store\BuildMetaStore::getByBuildId()
+ * @uses \PHPCI\Model\BuildMeta
+ * @return \PHPCI\Model\BuildMeta[]
+ */
+ public function getBuildBuildMetas()
+ {
+ return \b8\Store\Factory::getStore('BuildMeta')->getByBuildId($this->getId());
+ }
}
diff --git a/PHPCI/Model/Base/BuildMetaBase.php b/PHPCI/Model/Base/BuildMetaBase.php
new file mode 100644
index 00000000..f9aa94e5
--- /dev/null
+++ b/PHPCI/Model/Base/BuildMetaBase.php
@@ -0,0 +1,293 @@
+ null,
+ 'build_id' => null,
+ 'key' => null,
+ 'value' => null,
+ );
+
+ /**
+ * @var array
+ */
+ protected $getters = array(
+ 'id' => 'getId',
+ 'build_id' => 'getBuildId',
+ 'key' => 'getKey',
+ 'value' => 'getValue',
+ 'Build' => 'getBuild',
+ );
+
+ /**
+ * @var array
+ */
+ protected $setters = array(
+ 'id' => 'setId',
+ 'build_id' => 'setBuildId',
+ 'key' => 'setKey',
+ 'value' => 'setValue',
+ 'Build' => 'setBuild',
+ );
+
+ /**
+ * @var array
+ */
+ public $columns = array(
+ 'id' => array(
+ 'type' => 'int',
+ 'length' => '10',
+ 'primary_key' => true,
+ 'auto_increment' => true,
+ ),
+ 'build_id' => array(
+ 'type' => 'int',
+ 'length' => '11',
+ ),
+ 'key' => array(
+ 'type' => 'varchar',
+ 'length' => '255',
+ ),
+ 'value' => array(
+ 'type' => 'text',
+ 'length' => '',
+ 'nullable' => true,
+ ),
+ );
+
+ /**
+ * @var array
+ */
+ public $indexes = array(
+ 'PRIMARY' => array('unique' => true, 'columns' => 'id'),
+ 'idx_meta_id' => array('unique' => true, 'columns' => 'build_id, key'),
+ );
+
+ /**
+ * @var array
+ */
+ public $foreignKeys = array(
+ 'fk_meta_build_id' => array(
+ 'local_col' => 'build_id',
+ 'update' => 'CASCADE',
+ 'delete' => 'CASCADE',
+ 'table' => 'build',
+ 'col' => 'id'
+ ),
+ );
+
+
+ /**
+ * Get the value of Id / id.
+ *
+ * @return int
+ */
+ public function getId()
+ {
+ $rtn = $this->data['id'];
+
+
+ return $rtn;
+ }
+
+ /**
+ * Get the value of BuildId / build_id.
+ *
+ * @return int
+ */
+ public function getBuildId()
+ {
+ $rtn = $this->data['build_id'];
+
+
+ return $rtn;
+ }
+
+ /**
+ * Get the value of Key / key.
+ *
+ * @return string
+ */
+ public function getKey()
+ {
+ $rtn = $this->data['key'];
+
+
+ return $rtn;
+ }
+
+ /**
+ * Get the value of Value / value.
+ *
+ * @return string
+ */
+ public function getValue()
+ {
+ $rtn = $this->data['value'];
+
+
+ return $rtn;
+ }
+
+ /**
+ * Set the value of Id / id.
+ *
+ * Must not be null.
+ * @param $value int
+ */
+ public function setId($value)
+ {
+ $this->_validateNotNull('Id', $value);
+ $this->_validateInt('Id', $value);
+ if ($this->data['id'] == $value) {
+ return;
+ }
+
+ $this->data['id'] = $value;
+
+ $this->_setModified('id');
+ }
+
+ /**
+ * Set the value of BuildId / build_id.
+ *
+ * Must not be null.
+ * @param $value int
+ */
+ public function setBuildId($value)
+ {
+ $this->_validateNotNull('BuildId', $value);
+ $this->_validateInt('BuildId', $value);
+ if ($this->data['build_id'] == $value) {
+ return;
+ }
+
+ $this->data['build_id'] = $value;
+
+ $this->_setModified('build_id');
+ }
+
+ /**
+ * Set the value of Key / key.
+ *
+ * Must not be null.
+ * @param $value string
+ */
+ public function setKey($value)
+ {
+ $this->_validateNotNull('Key', $value);
+ $this->_validateString('Key', $value);
+ if ($this->data['key'] == $value) {
+ return;
+ }
+
+ $this->data['key'] = $value;
+
+ $this->_setModified('key');
+ }
+
+ /**
+ * Set the value of Value / value.
+ *
+ * @param $value string
+ */
+ public function setValue($value)
+ {
+
+ $this->_validateString('Value', $value);
+ if ($this->data['value'] == $value) {
+ return;
+ }
+
+ $this->data['value'] = $value;
+
+ $this->_setModified('value');
+ }
+
+ /**
+ * Get the Build model for this BuildMeta by Id.
+ *
+ * @uses \PHPCI\Store\BuildStore::getById()
+ * @uses \PHPCI\Model\Build
+ * @return \PHPCI\Model\Build
+ */
+ public function getBuild()
+ {
+ $key = $this->getBuildId();
+
+ if (empty($key)) {
+ return null;
+ }
+
+ $cacheKey = 'Cache.Build.' . $key;
+ $rtn = $this->cache->get($cacheKey, null);
+
+ if (empty($rtn)) {
+ $rtn = \b8\Store\Factory::getStore('Build')->getById($key);
+ $this->cache->set($cacheKey, $rtn);
+ }
+
+ return $rtn;
+ }
+
+ /**
+ * Set Build - Accepts an ID, an array representing a Build or a Build model.
+ *
+ * @param $value mixed
+ */
+ public function setBuild($value)
+ {
+ // Is this an instance of Build?
+ if ($value instanceof \PHPCI\Model\Build) {
+ return $this->setBuildObject($value);
+ }
+
+ // Is this an array representing a Build item?
+ if (is_array($value) && !empty($value['id'])) {
+ return $this->setBuildId($value['id']);
+ }
+
+ // Is this a scalar value representing the ID of this foreign key?
+ return $this->setBuildId($value);
+ }
+
+ /**
+ * Set Build - Accepts a Build model.
+ *
+ * @param $value \PHPCI\Model\Build
+ */
+ public function setBuildObject(\PHPCI\Model\Build $value)
+ {
+ return $this->setBuildId($value->getId());
+ }
+}
diff --git a/PHPCI/Model/Base/ProjectBase.php b/PHPCI/Model/Base/ProjectBase.php
index 4e8b1e38..d00916bb 100644
--- a/PHPCI/Model/Base/ProjectBase.php
+++ b/PHPCI/Model/Base/ProjectBase.php
@@ -34,11 +34,11 @@ class ProjectBase extends Model
protected $data = array(
'id' => null,
'title' => null,
- 'access_information' => null,
'reference' => null,
'git_key' => null,
'type' => null,
'token' => null,
+ 'access_information' => null,
);
/**
@@ -50,8 +50,8 @@ class ProjectBase extends Model
'reference' => 'getReference',
'git_key' => 'getGitKey',
'type' => 'getType',
- 'access_information' => 'getAccessInformation',
'token' => 'getToken',
+ 'access_information' => 'getAccessInformation',
);
/**
@@ -63,8 +63,8 @@ class ProjectBase extends Model
'reference' => 'setReference',
'git_key' => 'setGitKey',
'type' => 'setType',
- 'access_information' => 'setAccessInformation',
'token' => 'setToken',
+ 'access_information' => 'setAccessInformation',
);
/**
@@ -85,10 +85,6 @@ class ProjectBase extends Model
'type' => 'varchar',
'length' => '250',
),
- 'access_information' => array(
- 'type' => 'varchar',
- 'length' => '250',
- ),
'git_key' => array(
'type' => 'text',
'length' => '',
@@ -102,6 +98,10 @@ class ProjectBase extends Model
'length' => '50',
'nullable' => true,
),
+ 'access_information' => array(
+ 'type' => 'varchar',
+ 'length' => '250',
+ ),
);
/**
@@ -157,19 +157,6 @@ class ProjectBase extends Model
return $rtn;
}
- /**
- * Get the value of Domain / domain.
- *
- * @return string
- */
- public function getAccessInformation()
- {
- $rtn = unserialize($this->data['access_information']);
-
-
- return $rtn;
- }
-
/**
* Get the value of GitKey / git_key.
*
@@ -209,6 +196,19 @@ class ProjectBase extends Model
return $rtn;
}
+ /**
+ * Get the value of AccessInformation / access_information.
+ *
+ * @return string
+ */
+ public function getAccessInformation()
+ {
+ $rtn = $this->data['access_information'];
+
+
+ return $rtn;
+ }
+
/**
* Set the value of Id / id.
*
@@ -266,25 +266,6 @@ class ProjectBase extends Model
$this->_setModified('reference');
}
- /**
- * Set the value of Domain / domain.
- *
- * Must not be null.
- * @param $value string
- */
- public function setAccessInformation($value)
- {
- $this->_validateNotNull('AccessInformation', $value);
- $this->_validateString('AccessInformation', $value);
- if ($this->data['access_information'] == $value) {
- return;
- }
-
- $this->data['access_information'] = $value;
-
- $this->_setModified('access_information');
- }
-
/**
* Set the value of GitKey / git_key.
*
@@ -341,6 +322,25 @@ class ProjectBase extends Model
$this->_setModified('token');
}
+ /**
+ * Set the value of AccessInformation / access_information.
+ *
+ * Must not be null.
+ * @param $value string
+ */
+ public function setAccessInformation($value)
+ {
+ $this->_validateNotNull('AccessInformation', $value);
+ $this->_validateString('AccessInformation', $value);
+ if ($this->data['access_information'] == $value) {
+ return;
+ }
+
+ $this->data['access_information'] = $value;
+
+ $this->_setModified('access_information');
+ }
+
/**
* Get Build models by ProjectId for this Project.
*
diff --git a/PHPCI/Model/BuildMeta.php b/PHPCI/Model/BuildMeta.php
new file mode 100644
index 00000000..afe50fb4
--- /dev/null
+++ b/PHPCI/Model/BuildMeta.php
@@ -0,0 +1,20 @@
+phpci->executeCommand($cmd, $standard, $suffixes, $ignore, $tab_width, $encoding, $this->phpci->buildPath . $this->path);
+ $success = $this->phpci->executeCommand($cmd, $standard, $suffixes, $ignore, $tab_width, $encoding, $this->phpci->buildPath . $this->path);
+
+ $output = $this->phpci->getLastOutput();
+
+ $matches = array();
+ if (preg_match_all('/WARNING/', $output, $matches)) {
+ $this->phpci->storeBuildMeta('phpcs-warnings', count($matches[0]));
+ }
+
+ $matches = array();
+ if (preg_match_all('/ERROR/', $output, $matches)) {
+ $this->phpci->storeBuildMeta('phpcs-errors', count($matches[0]));
+ }
+
+ return $success;
}
}
diff --git a/PHPCI/Plugin/PhpCpd.php b/PHPCI/Plugin/PhpCpd.php
index ecb54077..5a91dff4 100755
--- a/PHPCI/Plugin/PhpCpd.php
+++ b/PHPCI/Plugin/PhpCpd.php
@@ -57,6 +57,10 @@ class PhpCpd implements \PHPCI\Plugin
$ignore = implode('', $ignore);
}
- return $this->phpci->executeCommand(PHPCI_BIN_DIR . 'phpcpd %s "%s"', $ignore, $this->phpci->buildPath.$this->path);
+ $success = $this->phpci->executeCommand(PHPCI_BIN_DIR . 'phpcpd %s "%s"', $ignore, $this->phpci->buildPath.$this->path);
+
+ print $this->phpci->getLastOutput();
+
+ return $success;
}
}
diff --git a/PHPCI/Plugin/PhpLoc.php b/PHPCI/Plugin/PhpLoc.php
index 0ae62200..51ba7108 100644
--- a/PHPCI/Plugin/PhpLoc.php
+++ b/PHPCI/Plugin/PhpLoc.php
@@ -47,6 +47,18 @@ class PhpLoc implements \PHPCI\Plugin
$ignore = implode('', $ignore);
}
- return $this->phpci->executeCommand(PHPCI_BIN_DIR . 'phploc %s "%s"', $ignore, $this->phpci->buildPath);
+ $success = $this->phpci->executeCommand(PHPCI_BIN_DIR . 'phploc %s "%s"', $ignore, $this->phpci->buildPath);
+ $output = $this->phpci->getLastOutput();
+
+ if (preg_match_all('/\((LOC|CLOC|NCLOC|LLOC)\)\s+([0-9]+)/', $output, $matches)) {
+ $data = array();
+ foreach ($matches[1] as $k => $v) {
+ $data[$v] = (int)$matches[2][$k];
+ }
+
+ $this->phpci->storeBuildMeta('phploc', $data);
+ }
+
+ return $success;
}
}
\ No newline at end of file
diff --git a/PHPCI/Plugin/PhpMessDetector.php b/PHPCI/Plugin/PhpMessDetector.php
index 40ca3fcf..c395c3dd 100755
--- a/PHPCI/Plugin/PhpMessDetector.php
+++ b/PHPCI/Plugin/PhpMessDetector.php
@@ -83,6 +83,10 @@ class PhpMessDetector implements \PHPCI\Plugin
}
$cmd = PHPCI_BIN_DIR . 'phpmd "%s" text %s %s %s';
- return $this->phpci->executeCommand($cmd, $this->phpci->buildPath . $this->path, implode(',', $this->rules), $ignore, $suffixes);
+ $success = $this->phpci->executeCommand($cmd, $this->phpci->buildPath . $this->path, implode(',', $this->rules), $ignore, $suffixes);
+ $errors = count(array_filter(explode(PHP_EOL, $this->phpci->getLastOutput())));
+ $this->phpci->storeBuildMeta('phpmd-warnings', $errors);
+
+ return $success;
}
}
diff --git a/PHPCI/Store/Base/BuildMetaStoreBase.php b/PHPCI/Store/Base/BuildMetaStoreBase.php
new file mode 100644
index 00000000..b96b3875
--- /dev/null
+++ b/PHPCI/Store/Base/BuildMetaStoreBase.php
@@ -0,0 +1,86 @@
+getById($value, $useConnection);
+ }
+
+
+
+ public function getById($value, $useConnection = 'read')
+ {
+ if (is_null($value)) {
+ throw new \b8\Exception\HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
+ }
+
+ $query = 'SELECT * FROM build_meta WHERE id = :id LIMIT 1';
+ $stmt = \b8\Database::getConnection($useConnection)->prepare($query);
+ $stmt->bindValue(':id', $value);
+
+ if ($stmt->execute()) {
+ if ($data = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ return new \PHPCI\Model\BuildMeta($data);
+ }
+ }
+
+ return null;
+ }
+
+ public function getByBuildId($value, $limit = null, $useConnection = 'read')
+ {
+ if (is_null($value)) {
+ throw new \b8\Exception\HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
+ }
+
+ $add = '';
+
+ if ($limit) {
+ $add .= ' LIMIT ' . $limit;
+ }
+
+ $query = 'SELECT COUNT(*) AS cnt FROM build_meta WHERE build_id = :build_id' . $add;
+ $stmt = \b8\Database::getConnection($useConnection)->prepare($query);
+ $stmt->bindValue(':build_id', $value);
+
+ if ($stmt->execute()) {
+ $res = $stmt->fetch(\PDO::FETCH_ASSOC);
+ $count = (int)$res['cnt'];
+ } else {
+ $count = 0;
+ }
+
+ $query = 'SELECT * FROM build_meta WHERE build_id = :build_id' . $add;
+ $stmt = \b8\Database::getConnection('read')->prepare($query);
+ $stmt->bindValue(':build_id', $value);
+
+ if ($stmt->execute()) {
+ $res = $stmt->fetchAll(\PDO::FETCH_ASSOC);
+
+ $map = function ($item) {
+ return new \PHPCI\Model\BuildMeta($item);
+ };
+ $rtn = array_map($map, $res);
+
+ return array('items' => $rtn, 'count' => $count);
+ } else {
+ return array('items' => array(), 'count' => 0);
+ }
+ }
+}
diff --git a/PHPCI/Store/BuildMetaStore.php b/PHPCI/Store/BuildMetaStore.php
new file mode 100644
index 00000000..7450ac2a
--- /dev/null
+++ b/PHPCI/Store/BuildMetaStore.php
@@ -0,0 +1,20 @@
+ array(), 'count' => 0);
}
}
+
+ public function getMeta($key, $projectId, $buildId = null, $numResults = 1)
+ {
+ $and = $numResults > 1 ? ' AND (`build_id` <= :buildId) ' : ' AND (`build_id` = :buildId) ';
+ $query = 'SELECT `build_id`, `key`, `value` FROM `build_meta` WHERE `key` = :key AND `project_id` = :projectId ' . $and . ' ORDER BY id DESC LIMIT :numResults';
+
+ $stmt = \b8\Database::getConnection('read')->prepare($query);
+ $stmt->bindValue(':key', $key, \PDO::PARAM_STR);
+ $stmt->bindValue(':projectId', (int)$projectId, \PDO::PARAM_INT);
+ $stmt->bindValue(':buildId', (int)$buildId, \PDO::PARAM_INT);
+ $stmt->bindValue(':numResults', (int)$numResults, \PDO::PARAM_INT);
+
+ if ($stmt->execute()) {
+ $rtn = $stmt->fetchAll(\PDO::FETCH_ASSOC);
+
+ $rtn = array_reverse($rtn);
+ $rtn = array_map(function($item) {
+ $item['value'] = json_decode($item['value'], true);
+ return $item;
+ }, $rtn);
+
+ if (!count($rtn)) {
+ return null;
+ } else {
+ return $rtn;
+ }
+
+ } else {
+ return null;
+ }
+ }
+
+ public function setMeta($projectId, $buildId, $key, $value)
+ {
+ $query = 'REPLACE INTO build_meta (project_id, build_id, `key`, `value`) VALUES (:projectId, :buildId, :key, :value)';
+
+ $stmt = \b8\Database::getConnection('read')->prepare($query);
+ $stmt->bindValue(':key', $key, \PDO::PARAM_STR);
+ $stmt->bindValue(':projectId', (int)$projectId, \PDO::PARAM_INT);
+ $stmt->bindValue(':buildId', (int)$buildId, \PDO::PARAM_INT);
+ $stmt->bindValue(':value', $value, \PDO::PARAM_STR);
+
+ if ($stmt->execute()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
}
diff --git a/PHPCI/View/Build/view.phtml b/PHPCI/View/Build/view.phtml
index 25ea8809..a9cd569a 100644
--- a/PHPCI/View/Build/view.phtml
+++ b/PHPCI/View/Build/view.phtml
@@ -16,68 +16,27 @@
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 00000000..1776e983
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,1663 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
+ ],
+ "hash": "10373193ac4ded0a38f50fec0f5efeed",
+ "packages": [
+ {
+ "name": "atoum/atoum",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/atoum/atoum.git",
+ "reference": "befbdffcb72841cca0e1d2fb193a9b6cf1f957a4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/atoum/atoum/zipball/befbdffcb72841cca0e1d2fb193a9b6cf1f957a4",
+ "reference": "befbdffcb72841cca0e1d2fb193a9b6cf1f957a4",
+ "shasum": ""
+ },
+ "require": {
+ "ext-hash": "*",
+ "ext-json": "*",
+ "ext-session": "*",
+ "ext-tokenizer": "*",
+ "ext-xml": "*",
+ "php": ">=5.3.3"
+ },
+ "replace": {
+ "mageekguy/atoum": "*"
+ },
+ "suggest": {
+ "ext-mbstring": "Provides support for UTF-8 strings"
+ },
+ "bin": [
+ "bin/atoum"
+ ],
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "classes/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD"
+ ],
+ "authors": [
+ {
+ "name": "Frédéric Hardy",
+ "email": "frederic.hardy@atoum.org",
+ "homepage": "http://blog.mageekbox.net"
+ },
+ {
+ "name": "François Dussert",
+ "email": "francois.dussert@atoum.org"
+ },
+ {
+ "name": "Gérald Croes",
+ "email": "gerald.croes@atoum.org"
+ },
+ {
+ "name": "Julien Bianchi",
+ "email": "julien.bianchi@atoum.org"
+ },
+ {
+ "name": "Ludovic Fleury",
+ "email": "ludovic.fleury@atoum.org"
+ }
+ ],
+ "description": "Simple modern and intuitive unit testing framework for PHP 5.3+",
+ "homepage": "http://www.atoum.org",
+ "keywords": [
+ "TDD",
+ "atoum",
+ "test",
+ "unit testing"
+ ],
+ "time": "2013-10-02 12:05:26"
+ },
+ {
+ "name": "block8/b8framework",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Block8/b8framework.git",
+ "reference": "257b81a4a05a85225c372642456cb546b635e6c1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Block8/b8framework/zipball/257b81a4a05a85225c372642456cb546b635e6c1",
+ "reference": "257b81a4a05a85225c372642456cb546b635e6c1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "symfony/yaml": "2.2.x-dev"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "b8": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD"
+ ],
+ "authors": [
+ {
+ "name": "Block 8 Limited",
+ "email": "hello@block8.co.uk",
+ "homepage": "http://www.block8.co.uk"
+ }
+ ],
+ "description": "Simple, lightweight framework for high-throughput applications",
+ "homepage": "https://github.com/block8/b8framework",
+ "keywords": [
+ "b8",
+ "block8",
+ "framework",
+ "lightweight",
+ "mvc",
+ "php"
+ ],
+ "time": "2013-07-30 04:53:35"
+ },
+ {
+ "name": "fabpot/php-cs-fixer",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fabpot/PHP-CS-Fixer.git",
+ "reference": "f6c4f78b3e34c1c67c8ae4543f5d4b7232e23011"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fabpot/PHP-CS-Fixer/zipball/f6c4f78b3e34c1c67c8ae4543f5d4b7232e23011",
+ "reference": "f6c4f78b3e34c1c67c8ae4543f5d4b7232e23011",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/diff": "1.0.*@dev",
+ "symfony/console": "~2.1",
+ "symfony/filesystem": "~2.1",
+ "symfony/finder": "~2.1"
+ },
+ "bin": [
+ "php-cs-fixer"
+ ],
+ "type": "application",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\CS": "."
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ }
+ ],
+ "description": "A script to automatically fix Symfony Coding Standard",
+ "time": "2013-09-23 10:31:06"
+ },
+ {
+ "name": "ircmaxell/password-compat",
+ "version": "1.0.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ircmaxell/password_compat.git",
+ "reference": "1fc1521b5e9794ea77e4eca30717be9635f1d4f4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/1fc1521b5e9794ea77e4eca30717be9635f1d4f4",
+ "reference": "1fc1521b5e9794ea77e4eca30717be9635f1d4f4",
+ "shasum": ""
+ },
+ "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": "2013-04-30 19:58:08"
+ },
+ {
+ "name": "jakub-onderka/php-parallel-lint",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/JakubOnderka/PHP-Parallel-Lint.git",
+ "reference": "b3d054c8cb380fa77806ab108bbd689fb5d7beb7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/JakubOnderka/PHP-Parallel-Lint/zipball/b3d054c8cb380fa77806ab108bbd689fb5d7beb7",
+ "reference": "b3d054c8cb380fa77806ab108bbd689fb5d7beb7",
+ "shasum": ""
+ },
+ "bin": [
+ "run"
+ ],
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "./"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD"
+ ],
+ "authors": [
+ {
+ "name": "Jakub Onderka",
+ "email": "jakub.onderka@gmail.com",
+ "homepage": "http://acci.cz/"
+ }
+ ],
+ "description": "This tool check syntax of PHP files about 20x faster than serial check.",
+ "homepage": "https://github.com/JakubOnderka/PHP-Parallel-Lint",
+ "time": "2013-09-10 19:07:09"
+ },
+ {
+ "name": "pdepend/pdepend",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/pdepend/pdepend.git",
+ "reference": "820ceae75b405cd8ec49c5fd4c39a74ef1ea35d0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/pdepend/pdepend/zipball/820ceae75b405cd8ec49c5fd4c39a74ef1ea35d0",
+ "reference": "820ceae75b405cd8ec49c5fd4c39a74ef1ea35d0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "@stable",
+ "squizlabs/php_codesniffer": "@stable"
+ },
+ "bin": [
+ "src/bin/pdepend"
+ ],
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "description": "Official version of pdepend to be handled with Composer",
+ "time": "2013-10-03 11:41:37"
+ },
+ {
+ "name": "phploc/phploc",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phploc.git",
+ "reference": "41d3eb17c3a8185d9c7ee0138e3cf44bf6d053f4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/41d3eb17c3a8185d9c7ee0138e3cf44bf6d053f4",
+ "reference": "41d3eb17c3a8185d9c7ee0138e3cf44bf6d053f4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/finder-facade": ">=1.1.0",
+ "sebastian/git": ">=1.0.0",
+ "sebastian/version": ">=1.0.0",
+ "symfony/console": ">=2.2.0"
+ },
+ "bin": [
+ "composer/bin/phploc"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-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": "A tool for quickly measuring the size of a PHP project.",
+ "homepage": "https://github.com/sebastianbergmann/phploc",
+ "time": "2013-09-19 13:37:38"
+ },
+ {
+ "name": "phpmd/phpmd",
+ "version": "1.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpmd/phpmd.git",
+ "reference": "692b7b1b64518091b2b1bea91b489dbb13598c07"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpmd/phpmd/zipball/692b7b1b64518091b2b1bea91b489dbb13598c07",
+ "reference": "692b7b1b64518091b2b1bea91b489dbb13598c07",
+ "shasum": ""
+ },
+ "require": {
+ "pdepend/pdepend": ">=1.1.1",
+ "php": ">=5.3.0"
+ },
+ "bin": [
+ "src/bin/phpmd"
+ ],
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ "../../pdepend/pdepend/src/main/php",
+ "src/main/php"
+ ],
+ "description": "Official version of PHPMD handled with Composer.",
+ "time": "2013-07-26 14:47:02"
+ },
+ {
+ "name": "phpspec/php-diff",
+ "version": "v1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/php-diff.git",
+ "reference": "8d82ac415225fac373a4073ba14b1fe286aa2312"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/php-diff/zipball/8d82ac415225fac373a4073ba14b1fe286aa2312",
+ "reference": "8d82ac415225fac373a4073ba14b1fe286aa2312",
+ "shasum": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "Diff": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Chris Boulton",
+ "homepage": "http://github.com/chrisboulton"
+ }
+ ],
+ "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).",
+ "time": "2012-11-08 08:55:45"
+ },
+ {
+ "name": "phpspec/phpspec",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/phpspec.git",
+ "reference": "d8f64251d27dc1bb17b76608d620374b6b51f9ff"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/phpspec/zipball/d8f64251d27dc1bb17b76608d620374b6b51f9ff",
+ "reference": "d8f64251d27dc1bb17b76608d620374b6b51f9ff",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "phpspec/php-diff": "~1.0.0",
+ "phpspec/prophecy": "~1.0.2",
+ "symfony/console": "~2.1",
+ "symfony/event-dispatcher": "~2.1",
+ "symfony/finder": "~2.1",
+ "symfony/yaml": "~2.1"
+ },
+ "suggest": {
+ "whatthejeff/nyancat-scoreboard": "~1.1 – Enables the Nyan Cat formatter"
+ },
+ "bin": [
+ "bin/phpspec"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "PhpSpec": "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",
+ "homepage": "http://marcelloduarte.net/"
+ }
+ ],
+ "description": "Specification-oriented BDD framework for PHP 5.3+",
+ "homepage": "http://phpspec.net/",
+ "keywords": [
+ "BDD",
+ "SpecBDD",
+ "TDD",
+ "spec",
+ "specification",
+ "testing",
+ "tests"
+ ],
+ "time": "2013-10-04 08:02:36"
+ },
+ {
+ "name": "phpspec/prophecy",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "82d11835df7eccf904ea0c84fbb7304080346bc1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/82d11835df7eccf904ea0c84fbb7304080346bc1",
+ "reference": "82d11835df7eccf904ea0c84fbb7304080346bc1",
+ "shasum": ""
+ },
+ "require-dev": {
+ "phpspec/phpspec": "2.0.*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.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": "http://phpspec.org",
+ "keywords": [
+ "Double",
+ "Dummy",
+ "fake",
+ "mock",
+ "spy",
+ "stub"
+ ],
+ "time": "2013-09-30 08:21:23"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "1.2.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "466e7cd2554b4e264c9e3f31216d25ac0e5f3d94"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/466e7cd2554b4e264c9e3f31216d25ac0e5f3d94",
+ "reference": "466e7cd2554b4e264c9e3f31216d25ac0e5f3d94",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "phpunit/php-file-iterator": ">=1.3.0@stable",
+ "phpunit/php-text-template": ">=1.1.1@stable",
+ "phpunit/php-token-stream": ">=1.1.3@stable"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "3.7.*@dev"
+ },
+ "suggest": {
+ "ext-dom": "*",
+ "ext-xdebug": ">=2.0.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "PHP/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "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": "2013-09-10 08:14:32"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "2deb24c65ea78e126daa8d45b2089ddc29ec1d26"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/2deb24c65ea78e126daa8d45b2089ddc29ec1d26",
+ "reference": "2deb24c65ea78e126daa8d45b2089ddc29ec1d26",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "File/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "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": "2013-01-07 10:47:05"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "1eeef106193d2f8c539728e566bb4793071a9e18"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/1eeef106193d2f8c539728e566bb4793071a9e18",
+ "reference": "1eeef106193d2f8c539728e566bb4793071a9e18",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "Text/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "time": "2013-01-07 10:56:17"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "1.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
+ "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "PHP/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "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": "2013-08-02 07:42:54"
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "5220af2a7929aa35cf663d97c89ad3d50cf5fa3e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/5220af2a7929aa35cf663d97c89ad3d50cf5fa3e",
+ "reference": "5220af2a7929aa35cf663d97c89ad3d50cf5fa3e",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "PHP/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "keywords": [
+ "tokenizer"
+ ],
+ "time": "2013-09-13 04:58:23"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "3.7.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "4b024e753e3421837afbcca962c8724c58b39376"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4b024e753e3421837afbcca962c8724c58b39376",
+ "reference": "4b024e753e3421837afbcca962c8724c58b39376",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-pcre": "*",
+ "ext-reflection": "*",
+ "ext-spl": "*",
+ "php": ">=5.3.3",
+ "phpunit/php-code-coverage": "~1.2.1",
+ "phpunit/php-file-iterator": ">=1.3.1",
+ "phpunit/php-text-template": ">=1.1.1",
+ "phpunit/php-timer": ">=1.0.4",
+ "phpunit/phpunit-mock-objects": "~1.2.0",
+ "symfony/yaml": "~2.0"
+ },
+ "require-dev": {
+ "pear-pear/pear": "1.9.4"
+ },
+ "suggest": {
+ "ext-json": "*",
+ "ext-simplexml": "*",
+ "ext-tokenizer": "*",
+ "phpunit/php-invoker": ">=1.1.0,<1.2.0"
+ },
+ "bin": [
+ "composer/bin/phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.7.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "PHPUnit/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ "",
+ "../../symfony/yaml/"
+ ],
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "http://www.phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "time": "2013-09-16 03:09:52"
+ },
+ {
+ "name": "phpunit/phpunit-mock-objects",
+ "version": "1.2.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
+ "reference": "3e40f3b3f18c044a24688fe406440d7fd537744a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3e40f3b3f18c044a24688fe406440d7fd537744a",
+ "reference": "3e40f3b3f18c044a24688fe406440d7fd537744a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "phpunit/php-text-template": ">=1.1.1@stable"
+ },
+ "require-dev": {
+ "pear-pear/pear": "1.9.4",
+ "phpunit/phpunit": "3.7.*@dev"
+ },
+ "suggest": {
+ "ext-soap": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "PHPUnit/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "include-path": [
+ ""
+ ],
+ "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": "2013-07-23 04:42:59"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "6affc0bf53304452d7f296588f6d5837070b4789"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/6affc0bf53304452d7f296588f6d5837070b4789",
+ "reference": "6affc0bf53304452d7f296588f6d5837070b4789",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "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": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "http://www.github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff"
+ ],
+ "time": "2013-07-09 05:45:26"
+ },
+ {
+ "name": "sebastian/finder-facade",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/finder-facade.git",
+ "reference": "1e396fda3449fce9df032749fa4fa2619e0347e0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/1e396fda3449fce9df032749fa4fa2619e0347e0",
+ "reference": "1e396fda3449fce9df032749fa4fa2619e0347e0",
+ "shasum": ""
+ },
+ "require": {
+ "symfony/finder": ">=2.2.0",
+ "theseer/fdomdocument": ">=1.3.1"
+ },
+ "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": "FinderFacade is a convenience wrapper for Symfony's Finder component.",
+ "homepage": "https://github.com/sebastianbergmann/finder-facade",
+ "time": "2013-05-28 06:10:03"
+ },
+ {
+ "name": "sebastian/git",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/git.git",
+ "reference": "9df628c8c27522ba122f85d4ca8f13bd6fe8b9aa"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/git/zipball/9df628c8c27522ba122f85d4ca8f13bd6fe8b9aa",
+ "reference": "9df628c8c27522ba122f85d4ca8f13bd6fe8b9aa",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2-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": "Simple wrapper for Git",
+ "homepage": "http://www.github.com/sebastianbergmann/git",
+ "keywords": [
+ "git"
+ ],
+ "time": "2013-08-09 07:12:19"
+ },
+ {
+ "name": "sebastian/phpcpd",
+ "version": "1.4.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpcpd.git",
+ "reference": "090575dbd6486bff545a7426f98e988c8c597c1b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/090575dbd6486bff545a7426f98e988c8c597c1b",
+ "reference": "090575dbd6486bff545a7426f98e988c8c597c1b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "phpunit/php-timer": ">=1.0.4,<1.1.0",
+ "sebastian/finder-facade": "~1.1",
+ "sebastian/version": ">=1.0.0",
+ "symfony/finder": ">=2.1.2",
+ "theseer/fdomdocument": "~1.4",
+ "zetacomponents/base": ">=1.8",
+ "zetacomponents/console-tools": ">=1.6"
+ },
+ "bin": [
+ "composer/bin/phpcpd"
+ ],
+ "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": "Copy/Paste Detector (CPD) for PHP code.",
+ "homepage": "https://github.com/sebastianbergmann/phpcpd",
+ "time": "2013-07-30 14:37:42"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "b5ed060223916b485002b02605e20ba04a741f03"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b5ed060223916b485002b02605e20ba04a741f03",
+ "reference": "b5ed060223916b485002b02605e20ba04a741f03",
+ "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": "2013-07-31 05:26:57"
+ },
+ {
+ "name": "squizlabs/php_codesniffer",
+ "version": "1.5.0RC4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
+ "reference": "146a9b54e4adeaca0a3ae073e0a8a03570d6cc43"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/146a9b54e4adeaca0a3ae073e0a8a03570d6cc43",
+ "reference": "146a9b54e4adeaca0a3ae073e0a8a03570d6cc43",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=5.1.2"
+ },
+ "suggest": {
+ "phpunit/php-timer": "dev-master"
+ },
+ "bin": [
+ "scripts/phpcs"
+ ],
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "CodeSniffer.php",
+ "CodeSniffer/CLI.php",
+ "CodeSniffer/Exception.php",
+ "CodeSniffer/File.php",
+ "CodeSniffer/Report.php",
+ "CodeSniffer/Reporting.php",
+ "CodeSniffer/Sniff.php",
+ "CodeSniffer/Tokens.php",
+ "CodeSniffer/Reports/",
+ "CodeSniffer/CommentParser/",
+ "CodeSniffer/Tokenizers/",
+ "CodeSniffer/DocGenerators/",
+ "CodeSniffer/Standards/AbstractPatternSniff.php",
+ "CodeSniffer/Standards/AbstractScopeSniff.php",
+ "CodeSniffer/Standards/AbstractVariableSniff.php",
+ "CodeSniffer/Standards/IncorrectPatternException.php",
+ "CodeSniffer/Standards/Generic/Sniffs/",
+ "CodeSniffer/Standards/MySource/Sniffs/",
+ "CodeSniffer/Standards/PEAR/Sniffs/",
+ "CodeSniffer/Standards/PSR1/Sniffs/",
+ "CodeSniffer/Standards/PSR2/Sniffs/",
+ "CodeSniffer/Standards/Squiz/Sniffs/",
+ "CodeSniffer/Standards/Zend/Sniffs/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Greg Sherwood",
+ "role": "lead"
+ }
+ ],
+ "description": "PHP_CodeSniffer tokenises PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+ "homepage": "http://www.squizlabs.com/php-codesniffer",
+ "keywords": [
+ "phpcs",
+ "standards"
+ ],
+ "time": "2013-09-26 00:14:02"
+ },
+ {
+ "name": "swiftmailer/swiftmailer",
+ "version": "v5.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/swiftmailer/swiftmailer.git",
+ "reference": "e2915242824e32e28be3fc699c453c1d16fd6de1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/e2915242824e32e28be3fc699c453c1d16fd6de1",
+ "reference": "e2915242824e32e28be3fc699c453c1d16fd6de1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "lib/swift_required.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Chris Corbyn"
+ }
+ ],
+ "description": "Swiftmailer, free feature-rich PHP mailer",
+ "homepage": "http://swiftmailer.org",
+ "keywords": [
+ "mail",
+ "mailer"
+ ],
+ "time": "2013-04-30 17:35:30"
+ },
+ {
+ "name": "symfony/console",
+ "version": "2.2.x-dev",
+ "target-dir": "Symfony/Component/Console",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Console.git",
+ "reference": "7ec2f86df8a0164d1677368f43a4a548b80a1402"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Console/zipball/7ec2f86df8a0164d1677368f43a4a548b80a1402",
+ "reference": "7ec2f86df8a0164d1677368f43a4a548b80a1402",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Console\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Console Component",
+ "homepage": "http://symfony.com",
+ "time": "2013-09-25 05:58:50"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "dev-master",
+ "target-dir": "Symfony/Component/EventDispatcher",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/EventDispatcher.git",
+ "reference": "9b4fe5757870682eb2251e283228a66d938265a8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/9b4fe5757870682eb2251e283228a66d938265a8",
+ "reference": "9b4fe5757870682eb2251e283228a66d938265a8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "symfony/dependency-injection": "~2.0"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony EventDispatcher Component",
+ "homepage": "http://symfony.com",
+ "time": "2013-09-19 09:47:34"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "dev-master",
+ "target-dir": "Symfony/Component/Filesystem",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Filesystem.git",
+ "reference": "e558fd5d593ebe083dca199f52aed5374ab7b57a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Filesystem/zipball/e558fd5d593ebe083dca199f52aed5374ab7b57a",
+ "reference": "e558fd5d593ebe083dca199f52aed5374ab7b57a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Filesystem\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Filesystem Component",
+ "homepage": "http://symfony.com",
+ "time": "2013-09-27 14:57:51"
+ },
+ {
+ "name": "symfony/finder",
+ "version": "dev-master",
+ "target-dir": "Symfony/Component/Finder",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Finder.git",
+ "reference": "e2ce3164ab58b4d54612e630571f158035ee8603"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Finder/zipball/e2ce3164ab58b4d54612e630571f158035ee8603",
+ "reference": "e2ce3164ab58b4d54612e630571f158035ee8603",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Finder\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Finder Component",
+ "homepage": "http://symfony.com",
+ "time": "2013-09-19 09:47:34"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "2.2.x-dev",
+ "target-dir": "Symfony/Component/Yaml",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Yaml.git",
+ "reference": "bb697b6617b90c91b2a65d24ce32035afe5e3418"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/bb697b6617b90c91b2a65d24ce32035afe5e3418",
+ "reference": "bb697b6617b90c91b2a65d24ce32035afe5e3418",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.2-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\Yaml\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Yaml Component",
+ "homepage": "http://symfony.com",
+ "time": "2013-09-22 17:30:19"
+ },
+ {
+ "name": "theseer/fdomdocument",
+ "version": "1.4.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/fDOMDocument.git",
+ "reference": "871515e1a48aa216627ad7cbfc3516d0838578e1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/871515e1a48aa216627ad7cbfc3516d0838578e1",
+ "reference": "871515e1a48aa216627ad7cbfc3516d0838578e1",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "lib-libxml": "*",
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convinience and to simplify the usage of DOM.",
+ "homepage": "https://github.com/theseer/fDOMDocument",
+ "time": "2013-06-30 12:26:39"
+ },
+ {
+ "name": "zetacomponents/base",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zetacomponents/Base.git",
+ "reference": "642f63a8a72c32996f1aaf8a317fdf746bc32ce7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zetacomponents/Base/zipball/642f63a8a72c32996f1aaf8a317fdf746bc32ce7",
+ "reference": "642f63a8a72c32996f1aaf8a317fdf746bc32ce7",
+ "shasum": ""
+ },
+ "require-dev": {
+ "zetacomponents/unit-test": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Sergey Alexeev"
+ },
+ {
+ "name": "Sebastian Bergmann"
+ },
+ {
+ "name": "Jan Borsodi"
+ },
+ {
+ "name": "Raymond Bosman"
+ },
+ {
+ "name": "Frederik Holljen"
+ },
+ {
+ "name": "Kore Nordmann"
+ },
+ {
+ "name": "Derick Rethans"
+ },
+ {
+ "name": "Vadym Savchuk"
+ },
+ {
+ "name": "Tobias Schlitt"
+ },
+ {
+ "name": "Alexandru Stanoi"
+ }
+ ],
+ "description": "The Base package provides the basic infrastructure that all packages rely on. Therefore every component relies on this package.",
+ "homepage": "https://github.com/zetacomponents",
+ "time": "2012-05-21 11:21:36"
+ },
+ {
+ "name": "zetacomponents/console-tools",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/zetacomponents/ConsoleTools.git",
+ "reference": "90156abef01e4215fda8b9740f77c322f126fb02"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/zetacomponents/ConsoleTools/zipball/90156abef01e4215fda8b9740f77c322f126fb02",
+ "reference": "90156abef01e4215fda8b9740f77c322f126fb02",
+ "shasum": ""
+ },
+ "require": {
+ "zetacomponents/base": "*"
+ },
+ "require-dev": {
+ "zetacomponents/unit-test": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Sergey Alexeev"
+ },
+ {
+ "name": "Sebastian Bergmann"
+ },
+ {
+ "name": "Jan Borsodi"
+ },
+ {
+ "name": "Raymond Bosman"
+ },
+ {
+ "name": "Frederik Holljen"
+ },
+ {
+ "name": "Kore Nordmann"
+ },
+ {
+ "name": "Derick Rethans"
+ },
+ {
+ "name": "Vadym Savchuk"
+ },
+ {
+ "name": "Tobias Schlitt"
+ },
+ {
+ "name": "Alexandru Stanoi"
+ }
+ ],
+ "description": "A set of classes to do different actions with the console (also called shell). It can render a progress bar, tables and a status bar and contains a class for parsing command line options.",
+ "homepage": "https://github.com/zetacomponents",
+ "time": "2012-05-21 09:55:34"
+ }
+ ],
+ "packages-dev": [
+
+ ],
+ "aliases": [
+
+ ],
+ "minimum-stability": "dev",
+ "stability-flags": {
+ "block8/b8framework": 20,
+ "symfony/yaml": 20,
+ "fabpot/php-cs-fixer": 20,
+ "jakub-onderka/php-parallel-lint": 20
+ },
+ "platform": [
+
+ ],
+ "platform-dev": [
+
+ ]
+}
diff --git a/public/assets/css/phpci.css b/public/assets/css/phpci.css
index 50691f6a..6453f193 100644
--- a/public/assets/css/phpci.css
+++ b/public/assets/css/phpci.css
@@ -1,6 +1,6 @@
body
{
- background: #246;
+ background: #f9f9f9;
font-family: Roboto, Arial, Sans-Serif;
font-style: normal;
font-weight: 300;
@@ -9,8 +9,7 @@ body
#content
{
- background: #fff;
- border: 10px solid #369;
+ -border: 10px solid #369;
padding: 10px;
}
@@ -50,7 +49,6 @@ td .label {
#title
{
- background: #f8f8f8;
border-bottom: 1px solid #ccc;
margin: -10px -10px 15px -10px;
padding: 10px;
@@ -92,4 +90,41 @@ h3
.navbar-brand {
padding: 10px 15px;
-}
\ No newline at end of file
+}
+
+.box {
+ background: #fff;
+ box-shadow: 0 0 5px rgba(0,0,0,0.1);
+ margin-bottom: 15px;
+ padding: 10px;
+}
+ .box .title {
+ border-bottom: 1px solid #eee;
+ cursor: move;
+ font-size: 1.2em;
+ padding: 8px;
+ }
+
+ .box .box-content {
+ }
+
+ .box .box-content table, .box .box-content pre {
+ margin-bottom: 0;
+ }
+
+ .box .box-content pre {
+ background: #fff;
+ border: 0;
+ }
+
+.ui-sortable-placeholder {
+ border: 1px dashed #ccc;
+ background: #ffe;
+ height: 100px;
+ margin-bottom: 15px;
+ visibility: visible !important;
+}
+
+.ui-sortable-placeholder * { visibility: hidden; }
+
+.ui-plugin { padding-top: 15px; }
\ No newline at end of file
diff --git a/public/assets/js/build-plugins/loc.js b/public/assets/js/build-plugins/loc.js
new file mode 100644
index 00000000..70808f35
--- /dev/null
+++ b/public/assets/js/build-plugins/loc.js
@@ -0,0 +1,65 @@
+var locPlugin = PHPCI.UiPlugin.extend({
+ id: 'build-lines-chart',
+ css: 'col-lg-6 col-md-6 col-sm-12 col-xs-12',
+ title: 'Lines of Code',
+ lastData: null,
+ displayOnUpdate: false,
+
+ register: function() {
+ var self = this;
+ var query = PHPCI.registerQuery('phploc-lines', -1, {num_builds: 10, key: 'phploc'})
+
+ $(window).on('phploc-lines', function(data) {
+ self.onUpdate(data);
+ });
+
+ $(window).on('build-updated', function(data) {
+ if (data.queryData.status > 1) {
+ self.displayOnUpdate = true;
+ query();
+ }
+ });
+
+ google.load("visualization", "1", {packages:["corechart"]});
+ },
+
+ render: function() {
+ return $('
').text('This chart will display once the build has completed.');
+ },
+
+ onUpdate: function(e) {
+ this.lastData = e.queryData;
+
+ if (this.displayOnUpdate) {
+ this.displayChart();
+ }
+ },
+
+ displayChart: function() {
+ var build = this.lastData;
+
+ if (!build || !build.length) {
+ return;
+ }
+
+ $('#phploc-lines').empty().animate({height: '275px'});
+
+ var data = [["Build", "Lines", "Comment Lines", "Non-Comment Lines", "Logical Lines"]];
+ for (var idx in build) {
+ data.push(['Build ' + build[idx].build_id, parseInt(build[idx].value.LOC), parseInt(build[idx].value.CLOC), parseInt(build[idx].value.NCLOC), parseInt(build[idx].value.LLOC)]);
+ }
+
+ var data = google.visualization.arrayToDataTable(data);
+
+ var options = {
+ hAxis: {title: 'Builds'},
+ vAxis: {title: 'Lines'},
+ backgroundColor: { fill: 'transparent' }
+ };
+
+ var chart = new google.visualization.LineChart(document.getElementById('phploc-lines'));
+ chart.draw(data, options);
+ }
+});
+
+PHPCI.registerPlugin(new locPlugin());
\ No newline at end of file
diff --git a/public/assets/js/build-plugins/log.js b/public/assets/js/build-plugins/log.js
new file mode 100644
index 00000000..a283ccf8
--- /dev/null
+++ b/public/assets/js/build-plugins/log.js
@@ -0,0 +1,23 @@
+var logPlugin = PHPCI.UiPlugin.extend({
+ id: 'build-log',
+ css: 'col-lg-12 col-md-12 col-sm-12 col-xs-12',
+ title: 'Build Log',
+
+ init: function(){
+ this._super();
+ },
+
+ render: function() {
+ var container = $('
');
+ container.css({height: '300px', 'overflow-y': 'auto'});
+ container.html(PHPCI.buildData.log);
+
+ return container;
+ },
+
+ onUpdate: function(e) {
+ $('#build-log pre').html(e.queryData.log);
+ }
+});
+
+PHPCI.registerPlugin(new logPlugin());
\ No newline at end of file
diff --git a/public/assets/js/build-plugins/time.js b/public/assets/js/build-plugins/time.js
new file mode 100644
index 00000000..5705ed9a
--- /dev/null
+++ b/public/assets/js/build-plugins/time.js
@@ -0,0 +1,37 @@
+var timePlugin = PHPCI.UiPlugin.extend({
+ id: 'build-time',
+ css: 'col-lg-12 col-md-12 col-sm-12 col-xs-12',
+ title: null,
+ box: true,
+
+ init: function(){
+ this._super();
+ },
+
+ render: function() {
+ return '
' +
+ '' +
+ '' +
+ 'Build Created | ' +
+ 'Build Started | ' +
+ 'Build Finished | ' +
+ '
' +
+ '' +
+ '' +
+ '' +
+ '' + PHPCI.buildData.created + ' | ' +
+ '' + PHPCI.buildData.started + ' | ' +
+ '' + PHPCI.buildData.finished + ' | ' +
+ '
' +
+ '' +
+ '
';
+ },
+
+ onUpdate: function(build) {
+ $('#created').text(build.created);
+ $('#started').text(build.started);
+ $('#finished').text(build.finished);
+ }
+});
+
+PHPCI.registerPlugin(new timePlugin());
\ No newline at end of file
diff --git a/public/assets/js/build-plugins/warnings.js b/public/assets/js/build-plugins/warnings.js
new file mode 100644
index 00000000..0912e121
--- /dev/null
+++ b/public/assets/js/build-plugins/warnings.js
@@ -0,0 +1,98 @@
+var plugin = PHPCI.UiPlugin.extend({
+ id: 'build-warnings-chart',
+ css: 'col-lg-6 col-md-6 col-sm-12 col-xs-12',
+ title: 'Quality Trend',
+ data: {},
+ keys: null,
+ displayOnUpdate: false,
+
+ register: function() {
+ var self = this;
+ var query1 = PHPCI.registerQuery('phpmd-warnings', -1, {num_builds: 10, key: 'phpmd-warnings'})
+ var query2 = PHPCI.registerQuery('phpcs-warnings', -1, {num_builds: 10, key: 'phpcs-warnings'})
+ var query3 = PHPCI.registerQuery('phpcs-errors', -1, {num_builds: 10, key: 'phpcs-errors'})
+
+ $(window).on('phpmd-warnings phpcs-warnings phpcs-errors', function(data) {
+ self.onUpdate(data);
+ });
+
+ $(window).on('build-updated', function(data) {
+ if (data.queryData.status > 1) {
+ self.displayOnUpdate = true;
+ query1();
+ query2();
+ query3();
+ }
+ });
+
+ google.load("visualization", "1", {packages:["corechart"]});
+ },
+
+ render: function() {
+ return $('
').text('This chart will display once the build has completed.');
+ },
+
+ onUpdate: function(e) {
+ var self = this;
+ var build = e.queryData;
+
+ if (!build || !build.length) {
+ return;
+ }
+
+ for (var i in build) {
+ var buildId = build[i]['build_id'];
+ var metaKey = build[i]['key'];
+ var metaVal = build[i]['value'];
+
+ if (!self.data[buildId]) {
+ self.data[buildId] = {};
+ }
+
+ self.data[buildId][metaKey] = metaVal;
+ self.keys = Object.keys(self.data[buildId]);
+ }
+
+ if (self.displayOnUpdate) {
+ self.displayChart();
+ }
+ },
+
+ displayChart: function() {
+ var self = this;
+
+ $('#build-warnings').empty().animate({height: '275px'});
+
+ var titles = ['Build'];
+ var keys = self.keys;
+
+ for (var i in keys) {
+ var t = {'phpmd-warnings': 'PHPMD Warnings', 'phpcs-warnings': 'PHPCS Warnings', 'phpcs-errors': 'PHPCS Errors'};
+ titles.push(t[keys[i]]);
+ }
+
+ var data = [titles];
+
+ for (var build in self.data) {
+ var thisBuild = ['#' + build];
+
+ for (var i in keys) {
+ thisBuild.push(parseInt(self.data[build][keys[i]]));
+ }
+
+ data.push(thisBuild);
+ }
+
+ var data = google.visualization.arrayToDataTable(data);
+ var options = {
+ hAxis: {title: 'Build'},
+ vAxis: {title: 'Warnings'},
+ backgroundColor: { fill: 'transparent' }
+ };
+
+ var chart = new google.visualization.LineChart(document.getElementById('build-warnings'));
+ chart.draw(data, options);
+ }
+});
+
+PHPCI.registerPlugin(new plugin());
\ No newline at end of file
diff --git a/public/assets/js/class.js b/public/assets/js/class.js
new file mode 100644
index 00000000..785e7aaf
--- /dev/null
+++ b/public/assets/js/class.js
@@ -0,0 +1,64 @@
+/* Simple JavaScript Inheritance
+ * By John Resig http://ejohn.org/
+ * MIT Licensed.
+ */
+// Inspired by base2 and Prototype
+(function(){
+ var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
+
+ // The base Class implementation (does nothing)
+ this.Class = function(){};
+
+ // Create a new Class that inherits from this class
+ Class.extend = function(prop) {
+ var _super = this.prototype;
+
+ // Instantiate a base class (but only create the instance,
+ // don't run the init constructor)
+ initializing = true;
+ var prototype = new this();
+ initializing = false;
+
+ // Copy the properties over onto the new prototype
+ for (var name in prop) {
+ // Check if we're overwriting an existing function
+ prototype[name] = typeof prop[name] == "function" &&
+ typeof _super[name] == "function" && fnTest.test(prop[name]) ?
+ (function(name, fn){
+ return function() {
+ var tmp = this._super;
+
+ // Add a new ._super() method that is the same method
+ // but on the super-class
+ this._super = _super[name];
+
+ // The method only need to be bound temporarily, so we
+ // remove it when we're done executing
+ var ret = fn.apply(this, arguments);
+ this._super = tmp;
+
+ return ret;
+ };
+ })(name, prop[name]) :
+ prop[name];
+ }
+
+ // The dummy class constructor
+ function Class() {
+ // All construction is actually done in the init method
+ if ( !initializing && this.init )
+ this.init.apply(this, arguments);
+ }
+
+ // Populate our constructed prototype object
+ Class.prototype = prototype;
+
+ // Enforce the constructor to be what we expect
+ Class.prototype.constructor = Class;
+
+ // And make this class extendable
+ Class.extend = arguments.callee;
+
+ return Class;
+ };
+})();
\ No newline at end of file
diff --git a/public/assets/js/jqueryui.js b/public/assets/js/jqueryui.js
new file mode 100755
index 00000000..dd1716c0
--- /dev/null
+++ b/public/assets/js/jqueryui.js
@@ -0,0 +1,6 @@
+/*! jQuery UI - v1.10.3 - 2013-10-06
+* http://jqueryui.com
+* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.sortable.js
+* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
+
+(function(e,t){function i(t,i){var s,a,o,r=t.nodeName.toLowerCase();return"area"===r?(s=t.parentNode,a=s.name,t.href&&a&&"map"===s.nodeName.toLowerCase()?(o=e("img[usemap=#"+a+"]")[0],!!o&&n(o)):!1):(/input|select|textarea|button|object/.test(r)?!t.disabled:"a"===r?t.href||i:i)&&n(t)}function n(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}var s=0,a=/^ui-id-\d+$/;e.ui=e.ui||{},e.extend(e.ui,{version:"1.10.3",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({focus:function(t){return function(i,n){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),n&&n.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),scrollParent:function(){var t;return t=e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(i){if(i!==t)return this.css("zIndex",i);if(this.length)for(var n,s,a=e(this[0]);a.length&&a[0]!==document;){if(n=a.css("position"),("absolute"===n||"relative"===n||"fixed"===n)&&(s=parseInt(a.css("zIndex"),10),!isNaN(s)&&0!==s))return s;a=a.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++s)})},removeUniqueId:function(){return this.each(function(){a.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,n){return!!e.data(t,n[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var n=e.attr(t,"tabindex"),s=isNaN(n);return(s||n>=0)&&i(t,!s)}}),e("
").outerWidth(1).jquery||e.each(["Width","Height"],function(i,n){function s(t,i,n,s){return e.each(a,function(){i-=parseFloat(e.css(t,"padding"+this))||0,n&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var a="Width"===n?["Left","Right"]:["Top","Bottom"],o=n.toLowerCase(),r={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+n]=function(i){return i===t?r["inner"+n].call(this):this.each(function(){e(this).css(o,s(this,i)+"px")})},e.fn["outer"+n]=function(t,i){return"number"!=typeof t?r["outer"+n].call(this,t):this.each(function(){e(this).css(o,s(this,t,!0,i)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,i,n){var s,a=e.ui[t].prototype;for(s in n)a.plugins[s]=a.plugins[s]||[],a.plugins[s].push([i,n[s]])},call:function(e,t,i){var n,s=e.plugins[t];if(s&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(n=0;s.length>n;n++)e.options[s[n][0]]&&s[n][1].apply(e.element,i)}},hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var n=i&&"left"===i?"scrollLeft":"scrollTop",s=!1;return t[n]>0?!0:(t[n]=1,s=t[n]>0,t[n]=0,s)}})})(jQuery);(function(t,e){var i=0,s=Array.prototype.slice,n=t.cleanData;t.cleanData=function(e){for(var i,s=0;null!=(i=e[s]);s++)try{t(i).triggerHandler("remove")}catch(o){}n(e)},t.widget=function(i,s,n){var o,a,r,h,l={},c=i.split(".")[0];i=i.split(".")[1],o=c+"-"+i,n||(n=s,s=t.Widget),t.expr[":"][o.toLowerCase()]=function(e){return!!t.data(e,o)},t[c]=t[c]||{},a=t[c][i],r=t[c][i]=function(t,i){return this._createWidget?(arguments.length&&this._createWidget(t,i),e):new r(t,i)},t.extend(r,a,{version:n.version,_proto:t.extend({},n),_childConstructors:[]}),h=new s,h.options=t.widget.extend({},h.options),t.each(n,function(i,n){return t.isFunction(n)?(l[i]=function(){var t=function(){return s.prototype[i].apply(this,arguments)},e=function(t){return s.prototype[i].apply(this,t)};return function(){var i,s=this._super,o=this._superApply;return this._super=t,this._superApply=e,i=n.apply(this,arguments),this._super=s,this._superApply=o,i}}(),e):(l[i]=n,e)}),r.prototype=t.widget.extend(h,{widgetEventPrefix:a?h.widgetEventPrefix:i},l,{constructor:r,namespace:c,widgetName:i,widgetFullName:o}),a?(t.each(a._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,r,i._proto)}),delete a._childConstructors):s._childConstructors.push(r),t.widget.bridge(i,r)},t.widget.extend=function(i){for(var n,o,a=s.call(arguments,1),r=0,h=a.length;h>r;r++)for(n in a[r])o=a[r][n],a[r].hasOwnProperty(n)&&o!==e&&(i[n]=t.isPlainObject(o)?t.isPlainObject(i[n])?t.widget.extend({},i[n],o):t.widget.extend({},o):o);return i},t.widget.bridge=function(i,n){var o=n.prototype.widgetFullName||i;t.fn[i]=function(a){var r="string"==typeof a,h=s.call(arguments,1),l=this;return a=!r&&h.length?t.widget.extend.apply(null,[a].concat(h)):a,r?this.each(function(){var s,n=t.data(this,o);return n?t.isFunction(n[a])&&"_"!==a.charAt(0)?(s=n[a].apply(n,h),s!==n&&s!==e?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):e):t.error("no such method '"+a+"' for "+i+" widget instance"):t.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+a+"'")}):this.each(function(){var e=t.data(this,o);e?e.option(a||{})._init():t.data(this,o,new n(a,this))}),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"",options:{disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this.bindings=t(),this.hoverable=t(),this.focusable=t(),s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:t.noop,_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(t.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:t.noop,widget:function(){return this.element},option:function(i,s){var n,o,a,r=i;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof i)if(r={},n=i.split("."),i=n.shift(),n.length){for(o=r[i]=t.widget.extend({},this.options[i]),a=0;n.length-1>a;a++)o[n[a]]=o[n[a]]||{},o=o[n[a]];if(i=n.pop(),s===e)return o[i]===e?null:o[i];o[i]=s}else{if(s===e)return this.options[i]===e?null:this.options[i];r[i]=s}return this._setOptions(r),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return this.options[t]=e,"disabled"===t&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!e).attr("aria-disabled",e),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var o,a=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=o=t(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,o=this.widget()),t.each(n,function(n,r){function h(){return i||a.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof r?a[r]:r).apply(a,arguments):e}"string"!=typeof r&&(h.guid=r.guid=r.guid||h.guid||t.guid++);var l=n.match(/^(\w+)\s*(.*)$/),c=l[1]+a.eventNamespace,u=l[2];u?o.delegate(u,c,h):s.bind(c,h)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(e).undelegate(e)},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){t(e.currentTarget).addClass("ui-state-hover")},mouseleave:function(e){t(e.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){t(e.currentTarget).addClass("ui-state-focus")},focusout:function(e){t(e.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}})})(jQuery);(function(t){var e=!1;t(document).mouseup(function(){e=!1}),t.widget("ui.mouse",{version:"1.10.3",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.bind("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).bind("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!e){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,n=1===i.which,a="string"==typeof this.options.cancel&&i.target.nodeName?t(i.target).closest(this.options.cancel).length:!1;return n&&!a&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===t.data(i.target,this.widgetName+".preventClickEvent")&&t.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return s._mouseMove(t)},this._mouseUpDelegate=function(t){return s._mouseUp(t)},t(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),e=!0,!0)):!0}},_mouseMove:function(e){return t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button?this._mouseUp(e):this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){return t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),!1},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery);(function(t){function e(t,e,i){return t>e&&e+i>t}function i(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))}t.widget("ui.sortable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var t=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===t.axis||i(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_setOption:function(e,i){"disabled"===e?(this.options[e]=i,this.widget().toggleClass("ui-sortable-disabled",!!i)):t.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):undefined}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY
=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var i="x"===this.options.axis||e(this.positionAbs.top+this.offset.click.top,t.top,t.height),s="y"===this.options.axis||e(this.positionAbs.left+this.offset.click.left,t.left,t.width),n=i&&s,o=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return n?this.floating?a&&"right"===a||"down"===o?2:1:o&&("down"===o?2:1):!1},_intersectsWithSides:function(t){var i=e(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),s=e(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),n=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return this.floating&&o?"right"===o&&s||"left"===o&&!s:n&&("down"===n&&i||"up"===n&&!i)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){var i,s,n,o,a=[],r=[],h=this._connectWith();if(h&&e)for(i=h.length-1;i>=0;i--)for(n=t(h[i]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&r.push([t.isFunction(o.options.items)?o.options.items.call(o.element):t(o.options.items,o.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),o]);for(r.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),i=r.length-1;i>=0;i--)r[i][0].each(function(){a.push(this)});return t(a)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",a),c.push({item:h,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]).addClass(i||e.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?e.currentItem.children().each(function(){t(" | ",e.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(n)}):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_contactContainers:function(s){var n,o,a,r,h,l,c,u,d,p,f=null,g=null;for(n=this.containers.length-1;n>=0;n--)if(!t.contains(this.currentItem[0],this.containers[n].element[0]))if(this._intersectsWith(this.containers[n].containerCache)){if(f&&t.contains(this.containers[n].element[0],f.element[0]))continue;f=this.containers[n],g=n}else this.containers[n].containerCache.over&&(this.containers[n]._trigger("out",s,this._uiHash(this)),this.containers[n].containerCache.over=0);if(f)if(1===this.containers.length)this.containers[g].containerCache.over||(this.containers[g]._trigger("over",s,this._uiHash(this)),this.containers[g].containerCache.over=1);else{for(a=1e4,r=null,p=f.floating||i(this.currentItem),h=p?"left":"top",l=p?"width":"height",c=this.positionAbs[h]+this.offset.click[h],o=this.items.length-1;o>=0;o--)t.contains(this.containers[g].element[0],this.items[o].item[0])&&this.items[o].item[0]!==this.currentItem[0]&&(!p||e(this.positionAbs.top+this.offset.click.top,this.items[o].top,this.items[o].height))&&(u=this.items[o].item.offset()[h],d=!1,Math.abs(u-c)>Math.abs(u+this.items[o][l]-c)&&(d=!0,u+=this.items[o][l]),a>Math.abs(u-c)&&(a=Math.abs(u-c),r=this.items[o],this.direction=d?"up":"down"));if(!r&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[g])return;r?this._rearrange(s,r,null,!0):this._rearrange(s,null,this.containers[g].element,!0),this._trigger("change",s,this._uiHash()),this.containers[g]._trigger("change",s,this._uiHash(this)),this.currentContainer=this.containers[g],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[g]._trigger("over",s,this._uiHash(this)),this.containers[g].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,t("document"===n.containment?document:window).width()-this.helperProportions.width-this.margins.left,(t("document"===n.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==document&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.leftthis.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)("auto"===this._storedCSS[i]||"static"===this._storedCSS[i])&&(this._storedCSS[i]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;i>=0;i--)e||s.push(function(t){return function(e){t._trigger("deactivate",e,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(function(t){return function(e){t._trigger("out",e,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!e){for(this._trigger("beforeStop",t,this._uiHash()),i=0;s.length>i;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!1}if(e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null,!e){for(i=0;s.length>i;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}})})(jQuery);
\ No newline at end of file
diff --git a/public/assets/js/phpci.js b/public/assets/js/phpci.js
index 5272daa9..c14c41bc 100644
--- a/public/assets/js/phpci.js
+++ b/public/assets/js/phpci.js
@@ -13,95 +13,6 @@ function confirmDelete(url)
}
}
-/**
-* Updates the build screen. Called at regular intervals on /build/view/X
-*/
-function updateBuildView(data)
-{
- $('#status').attr('class', 'alert');
-
- var cls;
- var msg;
-
- switch(data.status)
- {
- case 0:
- cls = 'alert-info';
- msg = 'This build has not yet started.';
- break;
-
- case 1:
- cls = 'alert-warning';
- msg = 'This build is in progress.';
- break;
-
- case 2:
- cls = 'alert-success';
- msg = 'This build was successful!';
- break;
-
- case 3:
- cls = 'alert-error';
- msg = 'This build has failed.';
- break;
- }
-
- $('#status').addClass(cls).text(msg);
-
- if(data.created)
- {
- $('#created').text(data.created);
- }
- else
- {
- $('#created').text('Not created yet.');
- }
-
- if(data.started)
- {
- $('#started').text(data.started);
- }
- else
- {
- $('#started').text('Not started yet.');
- }
-
- if(data.finished)
- {
- $('#finished').text(data.finished);
- }
- else
- {
- $('#finished').text('Not finished yet.');
- }
-
- if(data.plugins)
- {
- $('#plugins').empty();
-
- for(var plugin in data.plugins)
- {
- var row = $('').addClass(data.plugins[plugin] ? 'success' : 'error');
- var name = $('').html('' + formatPluginName(plugin) + '');
- var status = $(' | ').text(data.plugins[plugin] ? 'OK' : 'Failed');
-
- row.append(name);
- row.append(status);
- $('#plugins').append(row);
- }
- }
- else
- {
- var row = $(' |
');
- var col = $('').attr('colspan', 2).text('No plugins have run yet.');
-
- row.append(col);
- $('#plugins').empty().append(row);
- }
-
- $('#log').html(data.log);
-}
-
/**
* Used to initialise the project form:
*/
@@ -170,17 +81,129 @@ function setupProjectForm()
});
}
+var PHPCIObject = Class.extend({
+ buildId: null,
+ plugins: {},
+ observers: {},
+ buildData: {},
+ queries: {},
+ updateInterval: null,
-function formatPluginName (name) {
- name = name.replace(new RegExp('_', 'g'), ' ');
- name = ucwords(name);
- name = name.replace(new RegExp('Php', 'g'), 'PHP');
+ init: function(build) {
+ this.buildId = build;
+ this.registerQuery('build-updated', 10);
+ },
- return name;
-}
+ registerQuery: function(name, seconds, query) {
+ var self = this;
+ var uri = 'build/meta/' + self.buildId;
+ var query = query || {};
-function ucwords (str) {
- return (str + '').replace(/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g, function ($1) {
- return $1.toUpperCase();
- });
-}
\ No newline at end of file
+ if (name == 'build-updated') {
+ uri = 'build/data/' + self.buildId;
+ }
+
+ var cb = function() {
+ $.getJSON(window.PHPCI_URL + uri, query, function(data) {
+ $(window).trigger({type: name, queryData: data});
+ });
+ };
+
+ if (seconds != -1) {
+ setInterval(cb, seconds * 1000);
+ }
+
+ return cb;
+ },
+
+ registerPlugin: function(plugin) {
+ this.plugins[plugin.id] = plugin;
+ plugin.register();
+ },
+
+ storePluginOrder: function () {
+ var renderOrder = [];
+
+ $('.ui-plugin > div').each(function() {
+ renderOrder.push($(this).attr('id'));
+ });
+
+ localStorage.setItem('phpci-plugin-order', JSON.stringify(renderOrder));
+ },
+
+ renderPlugins: function() {
+ var self = this;
+ var rendered = [];
+ var renderOrder = localStorage.getItem('phpci-plugin-order');
+
+ if (renderOrder) {
+ renderOrder = JSON.parse(renderOrder);
+ } else {
+ renderOrder = ['build-time', 'build-lines-chart', 'build-warnings-chart', 'build-log'];
+ }
+
+ for (var idx in renderOrder) {
+ var key = renderOrder[idx];
+ self.renderPlugin(self.plugins[key]);
+ rendered.push(key);
+ }
+
+ for (var key in this.plugins) {
+ if (rendered.indexOf(key) == -1) {
+ self.renderPlugin(self.plugins[key]);
+ }
+ }
+
+ $('#plugins').sortable({
+ handle: '.title',
+ connectWith: '#plugins',
+ update: self.storePluginOrder
+ });
+
+ $(window).trigger({type: 'build-updated', queryData: self.buildData});
+ },
+
+ renderPlugin: function(plugin) {
+ var output = $('').addClass('box-content').append(plugin.render());
+ var container = $('').addClass('ui-plugin ' + plugin.css);
+ var content = $('').attr('id', plugin.id).append(output);
+
+ if (plugin.box) {
+ content.addClass('box');
+ }
+
+ if (plugin.title) {
+ content.prepend(''+plugin.title+'');
+ }
+
+ content.append(output);
+ container.append(content);
+
+ $('#plugins').append(container);
+ },
+
+ UiPlugin: Class.extend({
+ id: null,
+ css: 'col-lg-4 col-md-6 col-sm-12 col-xs-12',
+ box: true,
+
+ init: function(){
+ },
+
+ register: function() {
+ var self = this;
+
+ $(window).on('build-updated', function(data) {
+ self.onUpdate(data);
+ });
+ },
+
+ render: function () {
+ return '';
+ },
+
+ onUpdate: function (build) {
+
+ }
+ })
+});
\ No newline at end of file
|