Version 5.1 - All the GraphQL #32

Closed
timw4mail wants to merge 1160 commits from develop into master
46 changed files with 1203 additions and 943 deletions
Showing only changes of commit ce44761420 - Show all commits

View File

@ -36,5 +36,4 @@
</table>
</form>
</main>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/anime_collection') ?>"></script>
<?php endif ?>

View File

@ -98,6 +98,3 @@
<?php endforeach ?>
<?php endif ?>
</main>
<?php if ($auth->isAuthenticated()): ?>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/edit') ?>"></script>
<?php endif ?>

View File

@ -109,5 +109,4 @@
</form>
</fieldset>
</main>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/edit') ?>"></script>
<?php endif ?>

View File

@ -94,5 +94,4 @@
<?php endforeach ?>
<?php endif ?>
</main>
<?php $group = ($auth->isAuthenticated()) ? 'table_edit' : 'table' ?>
<script defer="defer" src="<?= $urlGenerator->assetUrl("js.php/g/{$group}") ?>"></script>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js/tables.min.js') ?>"></script>

View File

@ -39,5 +39,4 @@
</table>
</form>
</main>
<script defer="defer" src="<?= $urlGenerator->assetUrl("js.php/g/{$collection_type}_collection") ?>"></script>
<?php endif ?>

View File

@ -64,5 +64,4 @@
</form>
</fieldset>
</main>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/anime_collection') ?>"></script>
<?php endif ?>

View File

@ -39,4 +39,4 @@
</div>
<?php endif ?>
</main>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/table') ?>"></script>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js/tables.min.js') ?>"></script>

View File

@ -10,6 +10,10 @@
</div>
</div>
</section>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/event') ?>"></script>
<?php if ($auth->isAuthenticated()): ?>
<script async="async" defer="defer" src="<?= $urlGenerator->assetUrl('js/scripts-authed.min.js') ?>"></script>
<?php else: ?>
<script async="async" defer="defer" src="<?= $urlGenerator->assetUrl('js/scripts.min.js') ?>"></script>
<?php endif ?>
</body>
</html>

View File

@ -21,7 +21,7 @@
<link rel="icon" type="image/png" sizes="32x32" href="<?= $urlGenerator->assetUrl('images/icons/favicon-32x32.png') ?>">
<link rel="icon" type="image/png" sizes="96x96" href="<?= $urlGenerator->assetUrl('images/icons/favicon-96x96.png') ?>">
<link rel="icon" type="image/png" sizes="16x16" href="<?= $urlGenerator->assetUrl('images/icons/favicon-16x16.png') ?>">
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/base') ?>"></script>
</head>
<body class="<?= $escape->attr($url_type) ?> list">
<?php include 'setup-check.php' ?>

View File

@ -36,5 +36,4 @@
</table>
</form>
</main>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/manga_collection') ?>"></script>
<?php endif ?>

View File

@ -88,6 +88,3 @@
<?php endforeach ?>
<?php endif ?>
</main>
<?php if ($auth->isAuthenticated()): ?>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/edit') ?>"></script>
<?php endif ?>

View File

@ -27,9 +27,9 @@
</div>
<div>
<h2><a rel="external" href="<?= $data['url'] ?>"><?= $data['title'] ?></a></h2>
<?php if( ! empty($data['en_title'])): ?>
<h3><?= $data['en_title'] ?></h3>
<?php endif ?>
<?php foreach($data['titles'] as $title): ?>
<h3><?= $title ?></h3>
<?php endforeach ?>
<br />
<p><?= nl2br($data['synopsis']) ?></p>

View File

@ -72,4 +72,4 @@
<?php endforeach ?>
<?php endif ?>
</main>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js.php/g/table') ?>"></script>
<script defer="defer" src="<?= $urlGenerator->assetUrl('js/tables.min.js') ?>"></script>

12
app/views/settings.php Normal file
View File

@ -0,0 +1,12 @@
<?php
use function Aviat\AnimeClient\arrayToToml;
if ( ! $auth->isAuthenticated())
{
echo '<h1>Not Authorized</h1>';
}
?>

View File

@ -1,371 +0,0 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2017 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 4.0
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\EasyMin;
use function Amp\Promise\wait;
use Amp\Artax\Request;
use Aviat\AnimeClient\API\HummingbirdClient;
use Aviat\Ion\{Json, JsonException};
// Include Amp and Artax
require_once '../vendor/autoload.php';
//Creative rewriting of /g/groupname to ?g=groupname
$pi = $_SERVER['PATH_INFO'];
$pia = explode('/', $pi);
$piaLen = count($pia);
$i = 1;
while($i < $piaLen)
{
$j = $i+1;
$j = (isset($pia[$j])) ? $j : $i;
$_GET[$pia[$i]] = $pia[$j];
$i = $j + 1;
};
class FileNotChangedException extends \Exception {}
/**
* Simple Javascript minfier, using google closure compiler
*/
class JSMin {
protected $jsRoot;
protected $jsGroup;
protected $configFile;
protected $cacheFile;
protected $lastModified;
protected $requestedTime;
protected $cacheModified;
public function __construct(array $config, string $configFile)
{
$group = $_GET['g'];
$groups = $config['groups'];
$this->jsRoot = $config['js_root'];
$this->jsGroup = $groups[$group];
$this->configFile = $configFile;
$this->cacheFile = "{$this->jsRoot}cache/{$group}";
$this->lastModified = $this->getLastModified();
$this->cacheModified = (is_file($this->cacheFile))
? filemtime($this->cacheFile)
: 0;
// Output some JS!
$this->send();
}
protected function send()
{
// Override caching if debug key is set
if($this->isDebugCall())
{
return $this->output($this->getFiles());
}
// If the browser's cached version is up to date,
// don't resend the file
if($this->lastModified == $this->getIfModified() && $this->isNotDebug())
{
throw new FileNotChangedException();
}
if($this->cacheModified < $this->lastModified)
{
$js = $this->minify($this->getFiles());
//Make sure cache file gets created/updated
if (file_put_contents($this->cacheFile, $js) === FALSE)
{
echo 'Cache file was not created. Make sure you have the correct folder permissions.';
return;
}
return $this->output($js);
}
else
{
return $this->output(file_get_contents($this->cacheFile));
}
}
/**
* Makes a call to google closure compiler service
*
* @param array $options - Form parameters
* @throws \TypeError
* @return object
*/
protected function closureCall(array $options)
{
$formFields = http_build_query($options);
$request = (new Request('https://closure-compiler.appspot.com/compile'))
->withMethod('POST')
->withHeaders([
'Accept' => 'application/json',
'Accept-Encoding' => 'gzip',
'Content-type' => 'application/x-www-form-urlencoded'
])
->withBody($formFields);
$response = wait((new HummingbirdClient)->request($request, [
HummingbirdClient::OP_AUTO_ENCODING => false
]));
return $response;
}
/**
* Do a call to the closure compiler to check for compilation errors
*
* @param array $options
* @return void
*/
protected function checkMinifyErrors($options)
{
try
{
$errorRes = $this->closureCall($options);
$errorJson = wait($errorRes->getBody());
$errorObj = Json::decode($errorJson) ?: (object)[];
// Show error if exists
if ( ! empty($errorObj->errors) || ! empty($errorObj->serverErrors))
{
$errorJson = Json::encode($errorObj, JSON_PRETTY_PRINT);
header('Content-type: application/javascript');
echo "console.error(${errorJson});";
die();
}
}
catch (JsonException $e)
{
print_r($e);
die();
}
}
/**
* Get Files
*
* Concatenates the javascript files for the current
* group as a string
*
* @return string
*/
protected function getFiles()
{
$js = '';
foreach($this->jsGroup as $file)
{
$newFile = realpath("{$this->jsRoot}{$file}");
$js .= file_get_contents($newFile) . "\n\n";
}
return $js;
}
/**
* Get the most recent modified date
*
* @return int
*/
protected function getLastModified()
{
$modified = [];
foreach($this->jsGroup as $file)
{
$newFile = realpath("{$this->jsRoot}{$file}");
$modified[] = filemtime($newFile);
}
//Add this page too, as well as the groups file
$modified[] = filemtime(__FILE__);
$modified[] = filemtime($this->configFile);
rsort($modified);
$lastModified = $modified[0];
return $lastModified;
}
/**
* Minifies javascript using google's closure compiler
*
* @param string $js
* @return string
*/
protected function minify($js)
{
$options = [
'output_info' => 'errors',
'output_format' => 'json',
'compilation_level' => 'SIMPLE_OPTIMIZATIONS',
//'compilation_level' => 'ADVANCED_OPTIMIZATIONS',
'js_code' => $js,
'language' => 'ECMASCRIPT6_STRICT',
'language_out' => 'ECMASCRIPT5_STRICT'
];
// Check for errors
$this->checkMinifyErrors($options);
// Now actually retrieve the compiled code
$options['output_info'] = 'compiled_code';
$res = $this->closureCall($options);
$json = wait($res->getBody());
$obj = Json::decode($json);
//return $obj;
return $obj['compiledCode'];
}
/**
* Output the minified javascript
*
* @param string $js
* @return void
*/
protected function output($js)
{
$this->sendFinalOutput($js, 'application/javascript', $this->lastModified);
}
/**
* Get value of the if-modified-since header
*
* @return int - timestamp to compare for cache control
*/
protected function getIfModified()
{
return (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER))
? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])
: time();
}
/**
* Get value of etag to compare to hash of output
*
* @return string - the etag to compare
*/
protected function getIfNoneMatch()
{
return (array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER))
? $_SERVER['HTTP_IF_NONE_MATCH']
: '';
}
/**
* Determine whether or not to send debug version
*
* @return boolean
*/
protected function isNotDebug()
{
return ! $this->isDebugCall();
}
/**
* Determine whether or not to send debug version
*
* @return boolean
*/
protected function isDebugCall()
{
return array_key_exists('debug', $_GET);
}
/**
* Send actual output to browser
*
* @param string $content - the body of the response
* @param string $mimeType - the content type
* @param int $lastModified - the last modified date
* @return void
*/
protected function sendFinalOutput($content, $mimeType, $lastModified)
{
//This GZIPs the CSS for transmission to the user
//making file size smaller and transfer rate quicker
ob_start("ob_gzhandler");
$expires = $lastModified + 691200;
$lastModifiedDate = gmdate('D, d M Y H:i:s', $lastModified);
$expiresDate = gmdate('D, d M Y H:i:s', $expires);
header("Content-Type: {$mimeType}; charset=utf-8");
header('Cache-control: public, max-age=691200, must-revalidate');
header("Expires: {$expiresDate} GMT");
header("Last-Modified: {$lastModifiedDate} GMT");
header('X-Content-Type-Options: no-sniff');
echo $content;
ob_end_flush();
}
/**
* Send a 304 Not Modified header
*
* @return void
*/
public static function send304()
{
header('status: 304 Not Modified', true, 304);
}
}
// --------------------------------------------------------------------------
// ! Start Minifying
// --------------------------------------------------------------------------
$configFile = realpath(__DIR__ . '/../app/appConf/minify_config.php');
$config = require_once($configFile);
$groups = $config['groups'];
$cacheDir = "{$config['js_root']}cache";
if ( ! is_dir($cacheDir))
{
mkdir($cacheDir);
}
if ( ! array_key_exists($_GET['g'], $groups))
{
throw new InvalidArgumentException('You must specify a js group that exists');
}
try
{
new JSMin($config, $configFile);
}
catch (FileNotChangedException $e)
{
JSMin::send304();
}
//end of js.php

View File

@ -1,30 +0,0 @@
((_) => {
'use strict';
const search = (query) => {
// Show the loader
_.$('.cssload-loader')[0].removeAttribute('hidden');
// Do the api search
_.get(_.url('/anime-collection/search'), {query}, (searchResults, status) => {
searchResults = JSON.parse(searchResults);
// Hide the loader
_.$('.cssload-loader')[0].setAttribute('hidden', 'hidden');
// Show the results
_.$('#series_list')[0].innerHTML = render_anime_search_results(searchResults.data);
});
};
_.on('#search', 'keyup', _.throttle(250, function() {
const query = encodeURIComponent(this.value);
if (query === '') {
return;
}
search(query);
}));
})(AnimeClient);

View File

@ -1,70 +0,0 @@
/**
* Javascript for editing anime, if logged in
*/
((_) => {
'use strict';
// Action to increment episode count
_.on('body.anime.list', 'click', '.plus_one', (e) => {
let parentSel = _.closestParent(e.target, 'article');
let watchedCount = parseInt(_.$('.completed_number', parentSel)[0].textContent, 10) || 0;
let totalCount = parseInt(_.$('.total_number', parentSel)[0].textContent, 10);
let title = _.$('.name a', parentSel)[0].textContent;
// Setup the update data
let data = {
id: parentSel.dataset.kitsuId,
mal_id: parentSel.dataset.malId,
data: {
progress: watchedCount + 1
}
};
// If the episode count is 0, and incremented,
// change status to currently watching
if (isNaN(watchedCount) || watchedCount === 0) {
data.data.status = 'current';
}
// If you increment at the last episode, mark as completed
if (( ! isNaN(watchedCount)) && (watchedCount + 1) === totalCount) {
data.data.status = 'completed';
}
_.show(_.$('#loading-shadow')[0]);
// okay, lets actually make some changes!
_.ajax(_.url('/anime/update'), {
data,
dataType: 'json',
type: 'POST',
success: (res) => {
const resData = JSON.parse(res);
if (resData.errors) {
_.hide(_.$('#loading-shadow')[ 0 ]);
_.showMessage('error', `Failed to update ${title}. `);
_.scrollToTop();
return;
}
if (resData.data.attributes.status === 'completed') {
_.hide(parentSel);
}
_.hide(_.$('#loading-shadow')[0]);
_.showMessage('success', `Successfully updated ${title}`);
_.$('.completed_number', parentSel)[0].textContent = ++watchedCount;
_.scrollToTop();
},
error: (xhr, errorType, error) => {
_.hide(_.$('#loading-shadow')[0]);
_.showMessage('error', `Failed to update ${title}. `);
_.scrollToTop();
}
});
});
})(AnimeClient);

View File

@ -1,321 +0,0 @@
var AnimeClient = (function(w) {
'use strict';
// -------------------------------------------------------------------------
// ! Base
// -------------------------------------------------------------------------
function matches(elm, selector) {
let matches = (elm.document || elm.ownerDocument).querySelectorAll(selector),
i = matches.length;
while (--i >= 0 && matches.item(i) !== elm);
return i > -1;
}
const _ = {
/**
* Placeholder function
*/
noop: () => {},
/**
* DOM selector
*
* @param {string} selector - The dom selector string
* @param {object} context
* @return {array} - array of dom elements
*/
$(selector, context) {
if (typeof selector !== 'string') {
return selector;
}
context = (context != null && context.nodeType === 1)
? context
: document;
let elements = [];
if (selector.match(/^#([\w]+$)/)) {
elements.push(document.getElementById(selector.split('#')[1]));
} else {
elements = [].slice.apply(context.querySelectorAll(selector));
}
return elements;
},
/**
* Scroll to the top of the Page
*
* @return {void}
*/
scrollToTop() {
w.scroll(0,0);
},
/**
* Hide the selected element
*
* @param {string|Element} sel - the selector of the element to hide
* @return {void}
*/
hide(sel) {
sel.setAttribute('hidden', 'hidden');
},
/**
* UnHide the selected element
*
* @param {string|Element} sel - the selector of the element to hide
* @return {void}
*/
show(sel) {
sel.removeAttribute('hidden');
},
/**
* Display a message box
*
* @param {String} type - message type: info, error, success
* @param {String} message - the message itself
* @return {void}
*/
showMessage(type, message) {
let template =
`<div class='message ${type}'>
<span class='icon'></span>
${message}
<span class='close'></span>
</div>`;
let sel = AnimeClient.$('.message');
if (sel[0] !== undefined) {
sel[0].remove();
}
_.$('header')[0].insertAdjacentHTML('beforeend', template);
},
/**
* Finds the closest parent element matching the passed selector
*
* @param {DOMElement} current - the current DOMElement
* @param {string} parentSelector - selector for the parent element
* @return {DOMElement|null} - the parent element
*/
closestParent(current, parentSelector) {
if (Element.prototype.closest !== undefined) {
return current.closest(parentSelector);
}
while (current !== document.documentElement) {
if (matches(current, parentSelector)) {
return current;
}
current = current.parentElement;
}
return null;
},
/**
* Generate a full url from a relative path
*
* @param {String} path - url path
* @return {String} - full url
*/
url(path) {
let uri = `//${document.location.host}`;
uri += (path.charAt(0) === '/') ? path : `/${path}`;
return uri;
},
/**
* Throttle execution of a function
*
* @see https://remysharp.com/2010/07/21/throttling-function-calls
* @see https://jsfiddle.net/jonathansampson/m7G64/
* @param {Number} interval - the minimum throttle time in ms
* @param {Function} fn - the function to throttle
* @param {Object} scope - the 'this' object for the function
* @return {void}
*/
throttle(interval, fn, scope) {
var wait = false;
return function () {
var context = scope || this;
var args = arguments;
if ( ! wait) {
fn.apply(context, args);
wait = true;
setTimeout(function() {
wait = false;
}, interval);
}
};
},
};
// -------------------------------------------------------------------------
// ! Events
// -------------------------------------------------------------------------
function addEvent(sel, event, listener) {
// Recurse!
if (! event.match(/^([\w\-]+)$/)) {
event.split(' ').forEach((evt) => {
addEvent(sel, evt, listener);
});
}
sel.addEventListener(event, listener, false);
}
function delegateEvent(sel, target, event, listener) {
// Attach the listener to the parent
addEvent(sel, event, (e) => {
// Get live version of the target selector
_.$(target, sel).forEach((element) => {
if(e.target == element) {
listener.call(element, e);
e.stopPropagation();
}
});
});
}
/**
* Add an event listener
*
* @param {string|element} sel - the parent selector to bind to
* @param {string} event - event name(s) to bind
* @param {string|element} [target] - the element to directly bind the event to
* @param {function} listener - event listener callback
* @return {void}
*/
_.on = function (sel, event, target, listener) {
if (arguments.length === 3) {
listener = target;
_.$(sel).forEach((el) => {
addEvent(el, event, listener);
});
} else {
_.$(sel).forEach((el) => {
delegateEvent(el, target, event, listener);
});
}
};
// -------------------------------------------------------------------------
// ! Ajax
// -------------------------------------------------------------------------
/**
* Url encoding for non-get requests
*
* @param data
* @returns {string}
* @private
*/
function ajaxSerialize(data) {
let pairs = [];
Object.keys(data).forEach((name) => {
let value = data[name].toString();
name = encodeURIComponent(name);
value = encodeURIComponent(value);
pairs.push(`${name}=${value}`);
});
return pairs.join('&');
}
/**
* Make an ajax request
*
* Config:{
* data: // data to send with the request
* type: // http verb of the request, defaults to GET
* success: // success callback
* error: // error callback
* }
*
* @param {string} url - the url to request
* @param {Object} config - the configuration object
* @return {void}
*/
_.ajax = function(url, config) {
// Set some sane defaults
config = config || {};
config.data = config.data || {};
config.type = config.type || 'GET';
config.dataType = config.dataType || '';
config.success = config.success || _.noop;
config.mimeType = config.mimeType || 'application/x-www-form-urlencoded';
config.error = config.error || _.noop;
let request = new XMLHttpRequest();
let method = String(config.type).toUpperCase();
if (method === 'GET') {
url += (url.match(/\?/))
? ajaxSerialize(config.data)
: `?${ajaxSerialize(config.data)}`;
}
request.open(method, url);
request.onreadystatechange = () => {
if (request.readyState === 4) {
let responseText = '';
if (request.responseType === 'json') {
responseText = JSON.parse(request.responseText);
} else {
responseText = request.responseText;
}
if (request.status > 299) {
config.error.call(null, request.status, responseText, request.response);
} else {
config.success.call(null, responseText, request.status);
}
}
};
if (config.dataType === 'json') {
config.data = JSON.stringify(config.data);
config.mimeType = 'application/json';
} else {
config.data = ajaxSerialize(config.data);
}
request.setRequestHeader('Content-Type', config.mimeType);
switch (method) {
case 'GET':
request.send(null);
break;
default:
request.send(config.data);
break;
}
};
_.get = function(url, data, callback) {
if (arguments.length === 2) {
callback = data;
data = {};
}
return _.ajax(url, {
data,
success: callback
});
};
// -------------------------------------------------------------------------
// Export
// -------------------------------------------------------------------------
return _;
})(window);

View File

@ -1,30 +0,0 @@
/**
* Event handlers
*/
((ac) => {
'use strict';
// Close event for messages
ac.on('header', 'click', '.message', function () {
ac.hide(this);
});
// Confirm deleting of list or library items
ac.on('form.js-delete', 'submit', (event) => {
const proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');
if (proceed === false) {
event.preventDefault();
event.stopPropagation();
}
});
// Clear the api cache
ac.on('.js-clear-cache', 'click', () => {
ac.get('/cache_purge', () => {
ac.showMessage('success', 'Successfully purged api cache');
});
});
})(AnimeClient);

View File

View File

@ -1,23 +0,0 @@
((_) => {
'use strict';
const search = (query) => {
_.$('.cssload-loader')[0].removeAttribute('hidden');
_.get(_.url('/manga/search'), {query}, (searchResults, status) => {
searchResults = JSON.parse(searchResults);
_.$('.cssload-loader')[0].setAttribute('hidden', 'hidden');
_.$('#series_list')[0].innerHTML = render_manga_search_results(searchResults.data);
});
};
_.on('#search', 'keyup', _.throttle(250, function(e) {
let query = encodeURIComponent(this.value);
if (query === '') {
return;
}
search(query);
}));
})(AnimeClient);

View File

@ -1,69 +0,0 @@
/**
* Javascript for editing manga, if logged in
*/
((_) => {
'use strict';
_.on('.manga.list', 'click', '.edit_buttons button', (e) => {
let thisSel = e.target;
let parentSel = _.closestParent(e.target, 'article');
let type = thisSel.classList.contains('plus_one_chapter') ? 'chapter' : 'volume';
let completed = parseInt(_.$(`.${type}s_read`, parentSel)[0].textContent, 10) || 0;
let total = parseInt(_.$(`.${type}_count`, parentSel)[0].textContent, 10);
let mangaName = _.$('.name', parentSel)[0].textContent;
if (isNaN(completed)) {
completed = 0;
}
// Setup the update data
let data = {
id: parentSel.dataset.kitsuId,
mal_id: parentSel.dataset.malId,
data: {
progress: completed
}
};
// If the episode count is 0, and incremented,
// change status to currently reading
if (isNaN(completed) || completed === 0) {
data.data.status = 'current';
}
// If you increment at the last chapter, mark as completed
if (( ! isNaN(completed)) && (completed + 1) === total) {
data.data.status = 'completed';
}
// Update the total count
data.data.progress = ++completed;
_.show(_.$('#loading-shadow')[0]);
_.ajax(_.url('/manga/update'), {
data,
dataType: 'json',
type: 'POST',
mimeType: 'application/json',
success: () => {
if (data.data.status === 'completed') {
_.hide(parentSel);
}
_.hide(_.$('#loading-shadow')[0]);
_.$(`.${type}s_read`, parentSel)[0].textContent = completed;
_.showMessage('success', `Sucessfully updated ${mangaName}`);
_.scrollToTop();
},
error: () => {
_.hide(_.$('#loading-shadow')[0]);
_.showMessage('error', `Failed to update ${mangaName}`);
_.scrollToTop();
}
});
});
})(AnimeClient);

20
public/js/scripts-authed.min.js vendored Normal file
View File

@ -0,0 +1,20 @@
var e=e||{};e.scope={};e.ASSUME_ES5=!1;e.ASSUME_NO_NATIVE_MAP=!1;e.ASSUME_NO_NATIVE_SET=!1;e.defineProperty=e.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(c,g,l){c!=Array.prototype&&c!=Object.prototype&&(c[g]=l.value)};e.getGlobal=function(c){return"undefined"!=typeof window&&window===c?c:"undefined"!=typeof global&&null!=global?global:c};e.global=e.getGlobal(this);e.SYMBOL_PREFIX="jscomp_symbol_";
e.initSymbol=function(){e.initSymbol=function(){};e.global.Symbol||(e.global.Symbol=e.Symbol)};e.Symbol=function(){var c=0;return function(g){return e.SYMBOL_PREFIX+(g||"")+c++}}();e.initSymbolIterator=function(){e.initSymbol();var c=e.global.Symbol.iterator;c||(c=e.global.Symbol.iterator=e.global.Symbol("iterator"));"function"!=typeof Array.prototype[c]&&e.defineProperty(Array.prototype,c,{configurable:!0,writable:!0,value:function(){return e.arrayIterator(this)}});e.initSymbolIterator=function(){}};
e.arrayIterator=function(c){var g=0;return e.iteratorPrototype(function(){return g<c.length?{done:!1,value:c[g++]}:{done:!0}})};e.iteratorPrototype=function(c){e.initSymbolIterator();c={next:c};c[e.global.Symbol.iterator]=function(){return this};return c};
e.iteratorFromArray=function(c,g){e.initSymbolIterator();c instanceof String&&(c+="");var l=0,h={next:function(){if(l<c.length){var m=l++;return{value:g(m,c[m]),done:!1}}h.next=function(){return{done:!0,value:void 0}};return h.next()}};h[Symbol.iterator]=function(){return h};return h};
e.polyfill=function(c,g){if(g){var l=e.global;c=c.split(".");for(var h=0;h<c.length-1;h++){var m=c[h];m in l||(l[m]={});l=l[m]}c=c[c.length-1];h=l[c];g=g(h);g!=h&&null!=g&&e.defineProperty(l,c,{configurable:!0,writable:!0,value:g})}};e.polyfill("Array.prototype.keys",function(c){return c?c:function(){return e.iteratorFromArray(this,function(c){return c})}},"es6","es3");
(function(){function c(d){a.$(".cssload-loader")[0].removeAttribute("hidden");a.get(a.url("/manga/search"),{query:d},function(b){b=JSON.parse(b);a.$(".cssload-loader")[0].setAttribute("hidden","hidden");a.$("#series_list")[0].innerHTML=n(b.data)})}function g(d){a.$(".cssload-loader")[0].removeAttribute("hidden");a.get(a.url("/anime-collection/search"),{query:d},function(b){b=JSON.parse(b);a.$(".cssload-loader")[0].setAttribute("hidden","hidden");a.$("#series_list")[0].innerHTML=p(b.data)})}function l(a,
b,f){b.match(/^([\w\-]+)$/)||b.split(" ").forEach(function(b){l(a,b,f)});a.addEventListener(b,f,!1)}function h(d,b,f,c){l(d,f,function(f){a.$(b,d).forEach(function(b){f.target==b&&(c.call(b,f),f.stopPropagation())})})}function m(a){var b=[];Object.keys(a).forEach(function(f){var d=a[f].toString();f=encodeURIComponent(f);d=encodeURIComponent(d);b.push(f+"\x3d"+d)});return b.join("\x26")}function p(a){var b=[];a.forEach(function(a){var d=a.attributes,f=d.titles.reduce(function(b,a){return b+(a+"\x3cbr /\x3e")},
[]);b.push('\n\t\t\t\x3carticle class\x3d"media search"\x3e\n\t\t\t\t\x3cdiv class\x3d"name"\x3e\n\t\t\t\t\t\x3cinput type\x3d"radio" class\x3d"big-check" id\x3d"'+d.slug+'" name\x3d"id" value\x3d"'+a.id+'" /\x3e\n\t\t\t\t\t\x3clabel for\x3d"'+d.slug+'"\x3e\n\t\t\t\t\t\t\x3cimg src\x3d"/public/images/anime/'+a.id+'.jpg" alt\x3d"" width\x3d"220" /\x3e\n\t\t\t\t\t\t\x3cspan class\x3d"name"\x3e\n\t\t\t\t\t\t\t'+d.canonicalTitle+"\x3cbr /\x3e\n\t\t\t\t\t\t\t\x3csmall\x3e"+f+"\x3c/small\x3e\n\t\t\t\t\t\t\x3c/span\x3e\n\t\t\t\t\t\x3c/label\x3e\n\t\t\t\t\x3c/div\x3e\n\t\t\t\x3c/article\x3e\n\t\t")});
return b.join("")}function n(a){var b=[];a.forEach(function(a){var d=a.attributes,f=d.titles.reduce(function(b,a){return b+(a+"\x3cbr /\x3e")},[]);b.push('\n\t\t\t\x3carticle class\x3d"media search"\x3e\n\t\t\t\t\x3cdiv class\x3d"name"\x3e\n\t\t\t\t\t\x3cinput type\x3d"radio" class\x3d"big-check" id\x3d"'+d.slug+'" name\x3d"id" value\x3d"'+a.id+'" /\x3e\n\t\t\t\t\t\x3clabel for\x3d"'+d.slug+'"\x3e\n\t\t\t\t\t\t\x3cimg src\x3d"/public/images/manga/'+a.id+'.jpg" alt\x3d"" width\x3d"220" /\x3e\n\t\t\t\t\t\t\x3cspan class\x3d"name"\x3e\n\t\t\t\t\t\t\t'+
d.canonicalTitle+"\x3cbr /\x3e\n\t\t\t\t\t\t\t\x3csmall\x3e"+f+"\x3c/small\x3e\n\t\t\t\t\t\t\x3c/span\x3e\n\t\t\t\t\t\x3c/label\x3e\n\t\t\t\t\x3c/div\x3e\n\t\t\t\x3c/article\x3e\n\t\t")});return b.join("")}var a={noop:function(){},$:function(a,b){b=void 0===b?null:b;if("string"!==typeof a)return a;b=null!==b&&1===b.nodeType?b:document;var d=[];a.match(/^#([\w]+$)/)?d.push(document.getElementById(a.split("#")[1])):d=[].slice.apply(b.querySelectorAll(a));return d},hasElement:function(d){return 0<a.$(d).length},
scrollToTop:function(){window.scroll(0,0)},hide:function(a){a.setAttribute("hidden","hidden")},show:function(a){a.removeAttribute("hidden")},showMessage:function(d,b){d="\x3cdiv class\x3d'message "+d+"'\x3e\n\t\t\t\t\x3cspan class\x3d'icon'\x3e\x3c/span\x3e\n\t\t\t\t"+b+"\n\t\t\t\t\x3cspan class\x3d'close'\x3e\x3c/span\x3e\n\t\t\t\x3c/div\x3e";b=a.$(".message");void 0!==b[0]&&b[0].remove();a.$("header")[0].insertAdjacentHTML("beforeend",d)},closestParent:function(a,b){if(void 0!==Element.prototype.closest)return a.closest(b);
for(;a!==document.documentElement;){for(var d=a,c=(d.document||d.ownerDocument).querySelectorAll(b),k=c.length;0<=--k&&c.item(k)!==d;);if(-1<k)return a;a=a.parentElement}return null},url:function(a){var b="//"+document.location.host;return b+="/"===a.charAt(0)?a:"/"+a},throttle:function(a,b,f){var d=!1;return function(c){for(var k=[],g=0;g<arguments.length;++g)k[g-0]=arguments[g];g=f||this;d||(b.apply(g,k),d=!0,setTimeout(function(){d=!1},a))}},on:function(d,b,f,c){3===arguments.length?(c=f,a.$(d).forEach(function(a){l(a,
b,c)})):a.$(d).forEach(function(a){h(a,f,b,c)})},ajax:function(d,b){b=b||{};b.data=b.data||{};b.type=b.type||"GET";b.dataType=b.dataType||"";b.success=b.success||a.noop;b.mimeType=b.mimeType||"application/x-www-form-urlencoded";b.error=b.error||a.noop;var f=new XMLHttpRequest,c=String(b.type).toUpperCase();"GET"===c&&(d+=d.match(/\?/)?m(b.data):"?"+m(b.data));f.open(c,d);f.onreadystatechange=function(){if(4===f.readyState){var a="json"===f.responseType?JSON.parse(f.responseText):f.responseText;299<
f.status?b.error.call(null,f.status,a,f.response):b.success.call(null,a,f.status)}};"json"===b.dataType?(b.data=JSON.stringify(b.data),b.mimeType="application/json"):b.data=m(b.data);f.setRequestHeader("Content-Type",b.mimeType);switch(c){case "GET":f.send(null);break;default:f.send(b.data)}},get:function(d,b,c){c=void 0===c?null:c;null===c&&(c=b,b={});return a.ajax(d,{data:b,success:c})}};a.on("header","click",".message",function(){a.hide(this)});a.on("form.js-delete","submit",function(a){!1===confirm("Are you ABSOLUTELY SURE you want to delete this item?")&&
(a.preventDefault(),a.stopPropagation())});a.on(".js-clear-cache","click",function(){a.get("/cache_purge",function(){a.showMessage("success","Successfully purged api cache")})});if(a.hasElement(".anime #search"))a.on("#search","keyup",a.throttle(250,function(){var a=encodeURIComponent(this.value);""!==a&&g(a)}));a.on("body.anime.list","click",".plus_one",function(c){var b=a.closestParent(c.target,"article"),d=parseInt(a.$(".completed_number",b)[0].textContent,10)||0;c=parseInt(a.$(".total_number",
b)[0].textContent,10);var g=a.$(".name a",b)[0].textContent,k={id:b.dataset.kitsuId,mal_id:b.dataset.malId,data:{progress:d+1}};if(isNaN(d)||0===d)k.data.status="current";isNaN(d)||d+1!==c||(k.data.status="completed");a.show(a.$("#loading-shadow")[0]);a.ajax(a.url("/anime/update"),{data:k,dataType:"json",type:"POST",success:function(c){c=JSON.parse(c);c.errors?(a.hide(a.$("#loading-shadow")[0]),a.showMessage("error","Failed to update "+g+". ")):("completed"===c.data.attributes.status&&a.hide(b),a.hide(a.$("#loading-shadow")[0]),
a.showMessage("success","Successfully updated "+g),a.$(".completed_number",b)[0].textContent=++d);a.scrollToTop()},error:function(){a.hide(a.$("#loading-shadow")[0]);a.showMessage("error","Failed to update "+g+". ");a.scrollToTop()}})});if(a.hasElement(".manga #search"))a.on("#search","keyup",a.throttle(250,function(){var a=encodeURIComponent(this.value);""!==a&&c(a)}));a.on(".manga.list","click",".edit_buttons button",function(c){var b=c.target,d=a.closestParent(c.target,"article"),g=b.classList.contains("plus_one_chapter")?
"chapter":"volume",k=parseInt(a.$("."+g+"s_read",d)[0].textContent,10)||0;c=parseInt(a.$("."+g+"_count",d)[0].textContent,10);var l=a.$(".name",d)[0].textContent;isNaN(k)&&(k=0);var h={id:d.dataset.kitsuId,mal_id:d.dataset.malId,data:{progress:k}};if(isNaN(k)||0===k)h.data.status="current";isNaN(k)||k+1!==c||(h.data.status="completed");h.data.progress=++k;a.show(a.$("#loading-shadow")[0]);a.ajax(a.url("/manga/update"),{data:h,dataType:"json",type:"POST",mimeType:"application/json",success:function(){"completed"===
h.data.status&&a.hide(d);a.hide(a.$("#loading-shadow")[0]);a.$("."+g+"s_read",d)[0].textContent=k;a.showMessage("success","Sucessfully updated "+l);a.scrollToTop()},error:function(){a.hide(a.$("#loading-shadow")[0]);a.showMessage("error","Failed to update "+l);a.scrollToTop()}})})})();
//# sourceMappingURL=scripts-authed.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"scripts-authed.min.js.map","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"}

12
public/js/scripts.min.js vendored Normal file
View File

@ -0,0 +1,12 @@
var d=d||{};d.scope={};d.ASSUME_ES5=!1;d.ASSUME_NO_NATIVE_MAP=!1;d.ASSUME_NO_NATIVE_SET=!1;d.defineProperty=d.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,e,g){a!=Array.prototype&&a!=Object.prototype&&(a[e]=g.value)};d.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};d.global=d.getGlobal(this);d.SYMBOL_PREFIX="jscomp_symbol_";
d.initSymbol=function(){d.initSymbol=function(){};d.global.Symbol||(d.global.Symbol=d.Symbol)};d.Symbol=function(){var a=0;return function(e){return d.SYMBOL_PREFIX+(e||"")+a++}}();d.initSymbolIterator=function(){d.initSymbol();var a=d.global.Symbol.iterator;a||(a=d.global.Symbol.iterator=d.global.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&d.defineProperty(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return d.arrayIterator(this)}});d.initSymbolIterator=function(){}};
d.arrayIterator=function(a){var e=0;return d.iteratorPrototype(function(){return e<a.length?{done:!1,value:a[e++]}:{done:!0}})};d.iteratorPrototype=function(a){d.initSymbolIterator();a={next:a};a[d.global.Symbol.iterator]=function(){return this};return a};
d.iteratorFromArray=function(a,e){d.initSymbolIterator();a instanceof String&&(a+="");var g=0,f={next:function(){if(g<a.length){var c=g++;return{value:e(c,a[c]),done:!1}}f.next=function(){return{done:!0,value:void 0}};return f.next()}};f[Symbol.iterator]=function(){return f};return f};
d.polyfill=function(a,e){if(e){var g=d.global;a=a.split(".");for(var f=0;f<a.length-1;f++){var c=a[f];c in g||(g[c]={});g=g[c]}a=a[a.length-1];f=g[a];e=e(f);e!=f&&null!=e&&d.defineProperty(g,a,{configurable:!0,writable:!0,value:e})}};d.polyfill("Array.prototype.keys",function(a){return a?a:function(){return d.iteratorFromArray(this,function(a){return a})}},"es6","es3");
(function(){function a(c,b,h){b.match(/^([\w\-]+)$/)||b.split(" ").forEach(function(b){a(c,b,h)});c.addEventListener(b,h,!1)}function e(c,b,h,k){a(c,h,function(a){f.$(b,c).forEach(function(b){a.target==b&&(k.call(b,a),a.stopPropagation())})})}function g(c){var b=[];Object.keys(c).forEach(function(a){var h=c[a].toString();a=encodeURIComponent(a);h=encodeURIComponent(h);b.push(a+"\x3d"+h)});return b.join("\x26")}var f={noop:function(){},$:function(c,b){b=void 0===b?null:b;if("string"!==typeof c)return c;
b=null!==b&&1===b.nodeType?b:document;var a=[];c.match(/^#([\w]+$)/)?a.push(document.getElementById(c.split("#")[1])):a=[].slice.apply(b.querySelectorAll(c));return a},hasElement:function(a){return 0<f.$(a).length},scrollToTop:function(){window.scroll(0,0)},hide:function(a){a.setAttribute("hidden","hidden")},show:function(a){a.removeAttribute("hidden")},showMessage:function(a,b){a="\x3cdiv class\x3d'message "+a+"'\x3e\n\t\t\t\t\x3cspan class\x3d'icon'\x3e\x3c/span\x3e\n\t\t\t\t"+b+"\n\t\t\t\t\x3cspan class\x3d'close'\x3e\x3c/span\x3e\n\t\t\t\x3c/div\x3e";
b=f.$(".message");void 0!==b[0]&&b[0].remove();f.$("header")[0].insertAdjacentHTML("beforeend",a)},closestParent:function(a,b){if(void 0!==Element.prototype.closest)return a.closest(b);for(;a!==document.documentElement;){for(var c=a,f=(c.document||c.ownerDocument).querySelectorAll(b),e=f.length;0<=--e&&f.item(e)!==c;);if(-1<e)return a;a=a.parentElement}return null},url:function(a){var b="//"+document.location.host;return b+="/"===a.charAt(0)?a:"/"+a},throttle:function(a,b,h){var c=!1;return function(f){for(var e=
[],g=0;g<arguments.length;++g)e[g-0]=arguments[g];g=h||this;c||(b.apply(g,e),c=!0,setTimeout(function(){c=!1},a))}},on:function(c,b,h,g){3===arguments.length?(g=h,f.$(c).forEach(function(c){a(c,b,g)})):f.$(c).forEach(function(a){e(a,h,b,g)})},ajax:function(a,b){b=b||{};b.data=b.data||{};b.type=b.type||"GET";b.dataType=b.dataType||"";b.success=b.success||f.noop;b.mimeType=b.mimeType||"application/x-www-form-urlencoded";b.error=b.error||f.noop;var c=new XMLHttpRequest,e=String(b.type).toUpperCase();
"GET"===e&&(a+=a.match(/\?/)?g(b.data):"?"+g(b.data));c.open(e,a);c.onreadystatechange=function(){if(4===c.readyState){var a="json"===c.responseType?JSON.parse(c.responseText):c.responseText;299<c.status?b.error.call(null,c.status,a,c.response):b.success.call(null,a,c.status)}};"json"===b.dataType?(b.data=JSON.stringify(b.data),b.mimeType="application/json"):b.data=g(b.data);c.setRequestHeader("Content-Type",b.mimeType);switch(e){case "GET":c.send(null);break;default:c.send(b.data)}},get:function(a,
b,e){e=void 0===e?null:e;null===e&&(e=b,b={});return f.ajax(a,{data:b,success:e})}};f.on("header","click",".message",function(){f.hide(this)});f.on("form.js-delete","submit",function(a){!1===confirm("Are you ABSOLUTELY SURE you want to delete this item?")&&(a.preventDefault(),a.stopPropagation())});f.on(".js-clear-cache","click",function(){f.get("/cache_purge",function(){f.showMessage("success","Successfully purged api cache")})})})();
//# sourceMappingURL=scripts.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"scripts.min.js.map","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}

View File

@ -0,0 +1,30 @@
import _ from './base/AnimeClient';
import { render_anime_search_results } from './anime_search_results';
const search = (query) => {
// Show the loader
_.$('.cssload-loader')[ 0 ].removeAttribute('hidden');
// Do the api search
_.get(_.url('/anime-collection/search'), { query }, (searchResults, status) => {
searchResults = JSON.parse(searchResults);
// Hide the loader
_.$('.cssload-loader')[ 0 ].setAttribute('hidden', 'hidden');
// Show the results
_.$('#series_list')[ 0 ].innerHTML = render_anime_search_results(searchResults.data);
});
};
if (_.hasElement('.anime #search')) {
_.on('#search', 'keyup', _.throttle(250, function () {
const query = encodeURIComponent(this.value);
if (query === '') {
return;
}
search(query);
}));
}

View File

@ -0,0 +1,66 @@
/**
* Javascript for editing anime, if logged in
*/
import _ from './base/AnimeClient';
// Action to increment episode count
_.on('body.anime.list', 'click', '.plus_one', (e) => {
let parentSel = _.closestParent(e.target, 'article');
let watchedCount = parseInt(_.$('.completed_number', parentSel)[0].textContent, 10) || 0;
let totalCount = parseInt(_.$('.total_number', parentSel)[0].textContent, 10);
let title = _.$('.name a', parentSel)[0].textContent;
// Setup the update data
let data = {
id: parentSel.dataset.kitsuId,
mal_id: parentSel.dataset.malId,
data: {
progress: watchedCount + 1
}
};
// If the episode count is 0, and incremented,
// change status to currently watching
if (isNaN(watchedCount) || watchedCount === 0) {
data.data.status = 'current';
}
// If you increment at the last episode, mark as completed
if (( ! isNaN(watchedCount)) && (watchedCount + 1) === totalCount) {
data.data.status = 'completed';
}
_.show(_.$('#loading-shadow')[0]);
// okay, lets actually make some changes!
_.ajax(_.url('/anime/update'), {
data,
dataType: 'json',
type: 'POST',
success: (res) => {
const resData = JSON.parse(res);
if (resData.errors) {
_.hide(_.$('#loading-shadow')[ 0 ]);
_.showMessage('error', `Failed to update ${title}. `);
_.scrollToTop();
return;
}
if (resData.data.attributes.status === 'completed') {
_.hide(parentSel);
}
_.hide(_.$('#loading-shadow')[0]);
_.showMessage('success', `Successfully updated ${title}`);
_.$('.completed_number', parentSel)[0].textContent = ++watchedCount;
_.scrollToTop();
},
error: (xhr, errorType, error) => {
_.hide(_.$('#loading-shadow')[0]);
_.showMessage('error', `Failed to update ${title}. `);
_.scrollToTop();
}
});
});

View File

@ -1,4 +1,4 @@
function render_anime_search_results (data) {
export function render_anime_search_results (data) {
const results = [];
data.forEach(x => {

View File

@ -0,0 +1,331 @@
// -------------------------------------------------------------------------
// ! Base
// -------------------------------------------------------------------------
const matches = (elm, selector) => {
let matches = (elm.document || elm.ownerDocument).querySelectorAll(selector),
i = matches.length;
while (--i >= 0 && matches.item(i) !== elm);
return i > -1;
}
export const AnimeClient = {
/**
* Placeholder function
*/
noop: () => {},
/**
* DOM selector
*
* @param {string} selector - The dom selector string
* @param {object} [context]
* @return {[HTMLElement]} - array of dom elements
*/
$(selector, context = null) {
if (typeof selector !== 'string') {
return selector;
}
context = (context !== null && context.nodeType === 1)
? context
: document;
let elements = [];
if (selector.match(/^#([\w]+$)/)) {
elements.push(document.getElementById(selector.split('#')[1]));
} else {
elements = [].slice.apply(context.querySelectorAll(selector));
}
return elements;
},
/**
* Does the selector exist on the current page?
*
* @param {string} selector
* @returns {boolean}
*/
hasElement(selector) {
return AnimeClient.$(selector).length > 0;
},
/**
* Scroll to the top of the Page
*
* @return {void}
*/
scrollToTop() {
window.scroll(0,0);
},
/**
* Hide the selected element
*
* @param {string|Element} sel - the selector of the element to hide
* @return {void}
*/
hide(sel) {
sel.setAttribute('hidden', 'hidden');
},
/**
* UnHide the selected element
*
* @param {string|Element} sel - the selector of the element to hide
* @return {void}
*/
show(sel) {
sel.removeAttribute('hidden');
},
/**
* Display a message box
*
* @param {string} type - message type: info, error, success
* @param {string} message - the message itself
* @return {void}
*/
showMessage(type, message) {
let template =
`<div class='message ${type}'>
<span class='icon'></span>
${message}
<span class='close'></span>
</div>`;
let sel = AnimeClient.$('.message');
if (sel[0] !== undefined) {
sel[0].remove();
}
AnimeClient.$('header')[0].insertAdjacentHTML('beforeend', template);
},
/**
* Finds the closest parent element matching the passed selector
*
* @param {HTMLElement} current - the current HTMLElement
* @param {string} parentSelector - selector for the parent element
* @return {HTMLElement|null} - the parent element
*/
closestParent(current, parentSelector) {
if (Element.prototype.closest !== undefined) {
return current.closest(parentSelector);
}
while (current !== document.documentElement) {
if (matches(current, parentSelector)) {
return current;
}
current = current.parentElement;
}
return null;
},
/**
* Generate a full url from a relative path
*
* @param {string} path - url path
* @return {string} - full url
*/
url(path) {
let uri = `//${document.location.host}`;
uri += (path.charAt(0) === '/') ? path : `/${path}`;
return uri;
},
/**
* Throttle execution of a function
*
* @see https://remysharp.com/2010/07/21/throttling-function-calls
* @see https://jsfiddle.net/jonathansampson/m7G64/
* @param {Number} interval - the minimum throttle time in ms
* @param {Function} fn - the function to throttle
* @param {Object} [scope] - the 'this' object for the function
* @return {Function}
*/
throttle(interval, fn, scope) {
let wait = false;
return function (...args) {
const context = scope || this;
if ( ! wait) {
fn.apply(context, args);
wait = true;
setTimeout(function() {
wait = false;
}, interval);
}
};
},
};
// -------------------------------------------------------------------------
// ! Events
// -------------------------------------------------------------------------
function addEvent(sel, event, listener) {
// Recurse!
if (! event.match(/^([\w\-]+)$/)) {
event.split(' ').forEach((evt) => {
addEvent(sel, evt, listener);
});
}
sel.addEventListener(event, listener, false);
}
function delegateEvent(sel, target, event, listener) {
// Attach the listener to the parent
addEvent(sel, event, (e) => {
// Get live version of the target selector
AnimeClient.$(target, sel).forEach((element) => {
if(e.target == element) {
listener.call(element, e);
e.stopPropagation();
}
});
});
}
/**
* Add an event listener
*
* @param {string|HTMLElement} sel - the parent selector to bind to
* @param {string} event - event name(s) to bind
* @param {string|HTMLElement|function} target - the element to directly bind the event to
* @param {function} [listener] - event listener callback
* @return {void}
*/
AnimeClient.on = function (sel, event, target, listener) {
if (arguments.length === 3) {
listener = target;
AnimeClient.$(sel).forEach((el) => {
addEvent(el, event, listener);
});
} else {
AnimeClient.$(sel).forEach((el) => {
delegateEvent(el, target, event, listener);
});
}
};
// -------------------------------------------------------------------------
// ! Ajax
// -------------------------------------------------------------------------
/**
* Url encoding for non-get requests
*
* @param data
* @returns {string}
* @private
*/
function ajaxSerialize(data) {
let pairs = [];
Object.keys(data).forEach((name) => {
let value = data[name].toString();
name = encodeURIComponent(name);
value = encodeURIComponent(value);
pairs.push(`${name}=${value}`);
});
return pairs.join('&');
}
/**
* Make an ajax request
*
* Config:{
* data: // data to send with the request
* type: // http verb of the request, defaults to GET
* success: // success callback
* error: // error callback
* }
*
* @param {string} url - the url to request
* @param {Object} config - the configuration object
* @return {void}
*/
AnimeClient.ajax = function(url, config) {
// Set some sane defaults
config = config || {};
config.data = config.data || {};
config.type = config.type || 'GET';
config.dataType = config.dataType || '';
config.success = config.success || AnimeClient.noop;
config.mimeType = config.mimeType || 'application/x-www-form-urlencoded';
config.error = config.error || AnimeClient.noop;
let request = new XMLHttpRequest();
let method = String(config.type).toUpperCase();
if (method === 'GET') {
url += (url.match(/\?/))
? ajaxSerialize(config.data)
: `?${ajaxSerialize(config.data)}`;
}
request.open(method, url);
request.onreadystatechange = () => {
if (request.readyState === 4) {
let responseText = '';
if (request.responseType === 'json') {
responseText = JSON.parse(request.responseText);
} else {
responseText = request.responseText;
}
if (request.status > 299) {
config.error.call(null, request.status, responseText, request.response);
} else {
config.success.call(null, responseText, request.status);
}
}
};
if (config.dataType === 'json') {
config.data = JSON.stringify(config.data);
config.mimeType = 'application/json';
} else {
config.data = ajaxSerialize(config.data);
}
request.setRequestHeader('Content-Type', config.mimeType);
switch (method) {
case 'GET':
request.send(null);
break;
default:
request.send(config.data);
break;
}
};
/**
* Do a get request
*
* @param {string} url
* @param {object|function} data
* @param {function} [callback]
*/
AnimeClient.get = function(url, data, callback = null) {
if (callback === null) {
callback = data;
data = {};
}
return AnimeClient.ajax(url, {
data,
success: callback
});
};
// -------------------------------------------------------------------------
// Export
// -------------------------------------------------------------------------
export default AnimeClient;

View File

@ -0,0 +1,25 @@
import _ from './AnimeClient';
/**
* Event handlers
*/
// Close event for messages
_.on('header', 'click', '.message', function () {
_.hide(this);
});
// Confirm deleting of list or library items
_.on('form.js-delete', 'submit', (event) => {
const proceed = confirm('Are you ABSOLUTELY SURE you want to delete this item?');
if (proceed === false) {
event.preventDefault();
event.stopPropagation();
}
});
// Clear the api cache
_.on('.js-clear-cache', 'click', () => {
_.get('/cache_purge', () => {
_.showMessage('success', 'Successfully purged api cache');
});
});

View File

@ -1,4 +1,3 @@
'use strict';
const LightTableSorter = (() => {
let th = null;
let cellIndex = null;

View File

@ -0,0 +1,7 @@
import './base/events';
import './anime_collection';
import './anime_edit';
import './manga_collection';
import './manga_edit';

1
public/js/src/index.js Normal file
View File

@ -0,0 +1 @@
import './base/events';

View File

@ -0,0 +1,24 @@
import _ from './base/AnimeClient';
import { render_manga_search_results } from './manga_search_results'
const search = (query) => {
_.$('.cssload-loader')[0].removeAttribute('hidden');
_.get(_.url('/manga/search'), {query}, (searchResults, status) => {
searchResults = JSON.parse(searchResults);
_.$('.cssload-loader')[0].setAttribute('hidden', 'hidden');
_.$('#series_list')[0].innerHTML = render_manga_search_results(searchResults.data);
});
};
if (_.hasElement('.manga #search')) {
_.on('#search', 'keyup', _.throttle(250, function (e) {
let query = encodeURIComponent(this.value);
if (query === '') {
return;
}
search(query);
}));
}

View File

@ -0,0 +1,64 @@
import _ from './base/AnimeClient';
/**
* Javascript for editing manga, if logged in
*/
_.on('.manga.list', 'click', '.edit_buttons button', (e) => {
let thisSel = e.target;
let parentSel = _.closestParent(e.target, 'article');
let type = thisSel.classList.contains('plus_one_chapter') ? 'chapter' : 'volume';
let completed = parseInt(_.$(`.${type}s_read`, parentSel)[0].textContent, 10) || 0;
let total = parseInt(_.$(`.${type}_count`, parentSel)[0].textContent, 10);
let mangaName = _.$('.name', parentSel)[0].textContent;
if (isNaN(completed)) {
completed = 0;
}
// Setup the update data
let data = {
id: parentSel.dataset.kitsuId,
mal_id: parentSel.dataset.malId,
data: {
progress: completed
}
};
// If the episode count is 0, and incremented,
// change status to currently reading
if (isNaN(completed) || completed === 0) {
data.data.status = 'current';
}
// If you increment at the last chapter, mark as completed
if (( ! isNaN(completed)) && (completed + 1) === total) {
data.data.status = 'completed';
}
// Update the total count
data.data.progress = ++completed;
_.show(_.$('#loading-shadow')[0]);
_.ajax(_.url('/manga/update'), {
data,
dataType: 'json',
type: 'POST',
mimeType: 'application/json',
success: () => {
if (data.data.status === 'completed') {
_.hide(parentSel);
}
_.hide(_.$('#loading-shadow')[0]);
_.$(`.${type}s_read`, parentSel)[0].textContent = completed;
_.showMessage('success', `Sucessfully updated ${mangaName}`);
_.scrollToTop();
},
error: () => {
_.hide(_.$('#loading-shadow')[0]);
_.showMessage('error', `Failed to update ${mangaName}`);
_.scrollToTop();
}
});
});

View File

@ -1,4 +1,4 @@
function render_manga_search_results (data) {
export function render_manga_search_results (data) {
const results = [];
data.forEach(x => {

7
public/js/tables.min.js vendored Normal file
View File

@ -0,0 +1,7 @@
var b=b||{};b.scope={};b.ASSUME_ES5=!1;b.ASSUME_NO_NATIVE_MAP=!1;b.ASSUME_NO_NATIVE_SET=!1;b.defineProperty=b.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(a,c,e){a!=Array.prototype&&a!=Object.prototype&&(a[c]=e.value)};b.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};b.global=b.getGlobal(this);b.SYMBOL_PREFIX="jscomp_symbol_";
b.initSymbol=function(){b.initSymbol=function(){};b.global.Symbol||(b.global.Symbol=b.Symbol)};b.Symbol=function(){var a=0;return function(c){return b.SYMBOL_PREFIX+(c||"")+a++}}();b.initSymbolIterator=function(){b.initSymbol();var a=b.global.Symbol.iterator;a||(a=b.global.Symbol.iterator=b.global.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&b.defineProperty(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return b.arrayIterator(this)}});b.initSymbolIterator=function(){}};
b.arrayIterator=function(a){var c=0;return b.iteratorPrototype(function(){return c<a.length?{done:!1,value:a[c++]}:{done:!0}})};b.iteratorPrototype=function(a){b.initSymbolIterator();a={next:a};a[b.global.Symbol.iterator]=function(){return this};return a};b.polyfill=function(a,c){if(c){var e=b.global;a=a.split(".");for(var d=0;d<a.length-1;d++){var g=a[d];g in e||(e[g]={});e=e[g]}a=a[a.length-1];d=e[a];c=c(d);c!=d&&null!=c&&b.defineProperty(e,a,{configurable:!0,writable:!0,value:c})}};
b.polyfill("Array.from",function(a){return a?a:function(a,e,d){b.initSymbolIterator();e=null!=e?e:function(a){return a};var c=[],f=a[Symbol.iterator];if("function"==typeof f){a=f.call(a);for(var h=0;!(f=a.next()).done;)c.push(e.call(d,f.value,h++))}else for(f=a.length,h=0;h<f;h++)c.push(e.call(d,a[h],h));return c}},"es6","es3");
(function(){function a(a){d&&g!==a.target.cellIndex&&(d.classList.remove("sorting_asc","sorting_desc"),d.classList.add("sorting"),f="");d=a.target;if("th"===d.nodeName.toLowerCase()){g=d.cellIndex;var h=d.offsetParent.getElementsByTagName("tbody")[0];if(a=Array.from(h.rows))a.sort(e),"sorting_asc"===f&&a.reverse(),c(),h.innerHtml="",a.forEach(function(a){h.appendChild(a)})}}function c(){var a="sorting_asc"!==f?"sorting_asc":"sorting_desc";d.className=(d.className.replace(f,"")+" "+a).trim();return f=
a}function e(a,c){a=a.cells.item(g).textContent.toLowerCase();c=c.cells.item(g).textContent.toLowerCase();var d=parseInt(a,10);d&&(a=d,c=parseInt(c,10));return a>c?1:a<c?-1:0}var d=null,g=null,f="";return{init:function(){for(var c=document.getElementsByTagName("th"),d=[],e=0,f=c.length;e<f;e++){var g=c[e];g.classList.add("sorting");d.push(g.onclick=a)}return d}}})().init();
//# sourceMappingURL=tables.min.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"tables.min.js.map","sources":["src/base/sort_tables.js"],"sourcesContent":["const LightTableSorter = (() => {\n\tlet th = null;\n\tlet cellIndex = null;\n\tlet order = '';\n\tconst text = (row) => {\n\t\treturn row.cells.item(cellIndex).textContent.toLowerCase();\n\t};\n\tconst sort = (a, b) => {\n\t\tlet textA = text(a);\n\t\tlet textB = text(b);\n\t\tconst n = parseInt(textA, 10);\n\t\tif (n) {\n\t\t\ttextA = n;\n\t\t\ttextB = parseInt(textB, 10);\n\t\t}\n\t\tif (textA > textB) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (textA < textB) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn 0;\n\t};\n\tconst toggle = () => {\n\t\tconst c = order !== 'sorting_asc' ? 'sorting_asc' : 'sorting_desc';\n\t\tth.className = (th.className.replace(order, '') + ' ' + c).trim();\n\t\treturn order = c;\n\t};\n\tconst reset = () => {\n\t\tth.classList.remove('sorting_asc', 'sorting_desc');\n\t\tth.classList.add('sorting');\n\t\treturn order = '';\n\t};\n\tconst onClickEvent = (e) => {\n\t\tif (th && (cellIndex !== e.target.cellIndex)) {\n\t\t\treset();\n\t\t}\n\t\tth = e.target;\n\t\tif (th.nodeName.toLowerCase() === 'th') {\n\t\t\tcellIndex = th.cellIndex;\n\t\t\tconst tbody = th.offsetParent.getElementsByTagName('tbody')[0];\n\t\t\tlet rows = Array.from(tbody.rows);\n\t\t\tif (rows) {\n\t\t\t\trows.sort(sort);\n\t\t\t\tif (order === 'sorting_asc') {\n\t\t\t\t\trows.reverse();\n\t\t\t\t}\n\t\t\t\ttoggle();\n\t\t\t\ttbody.innerHtml = '';\n\n\t\t\t\trows.forEach(row => {\n\t\t\t\t\ttbody.appendChild(row);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\treturn {\n\t\tinit: () => {\n\t\t\tlet ths = document.getElementsByTagName('th');\n\t\t\tlet results = [];\n\t\t\tfor (let i = 0, len = ths.length; i < len; i++) {\n\t\t\t\tlet th = ths[i];\n\t\t\t\tth.classList.add('sorting');\n\t\t\t\tresults.push(th.onclick = onClickEvent);\n\t\t\t}\n\t\t\treturn results;\n\t\t}\n\t};\n})();\n\nLightTableSorter.init();"],"names":[],"mappings":"IAsBG,GAAA;;;;;;"}

View File

@ -1,13 +1,21 @@
{
"scripts": {
"build": "node ./css.js",
"watch": "watch 'npm run build' --filter=./cssfilter.js"
"build": "npm run build:css && npm run build:js",
"build:css": "node ./tools/css.js",
"build:js": "rollup -c ./tools/build-js.js",
"watch:css": "watch 'npm run build:css' --filter=./tools/cssfilter.js",
"watch:js": "watch 'npm run build:js' ./js/src",
"watch": "concurrently \"npm:watch:css\" \"npm:watch:js\" --kill-others"
},
"devDependencies": {
"concurrently": "^3.6.1",
"cssnano": "^4.0.5",
"postcss-cachify": "^1.3.1",
"postcss-cssnext": "^3.0.0",
"postcss-import": "^12.0.0",
"rollup": "^0.64.1",
"rollup-plugin-buble": "^0.19.2",
"rollup-plugin-closure-compiler-js": "^1.0.6",
"watch": "^1.0.2"
}
}

View File

@ -20,7 +20,7 @@
</ul>
<ul id="mocha-report"></ul>
</div>
<script src="../js/base/classList.js"></script>
<script src="../js/src/base/classList.js"></script>
<script src="lib/testBundle.js"></script>
<script>
@ -29,7 +29,7 @@
</script>
<!-- include source files here... -->
<script src="../js/base/AnimeClient.js"></script>
<script src="../js/src/base/AnimeClient.js"></script>
<!-- include test files here... -->
<script src="tests/AnimeClient.js"></script>

43
public/tools/build-js.js Normal file
View File

@ -0,0 +1,43 @@
import closure from 'rollup-plugin-closure-compiler-js';
const plugins = [
closure({
assumeFunctionWrapper: true,
compilationLevel: 'SIMPLE', //'WHITESPACE_ONLY', //'ADVANCED',
createSourceMap: true,
env: 'BROWSER',
languageIn: 'ES6',
languageOut: 'ES5'
})
];
export default [{
input: './js/src/index.js',
output: {
file: './js/scripts.min.js',
format: 'iife',
sourcemap: true,
sourcemapFile: './js/scripts.min.js.map',
},
plugins,
}, {
input: './js/src/index-authed.js',
output: {
file: './js/scripts-authed.min.js',
format: 'iife',
sourcemap: true,
sourcemapFile: './js/scripts-authed.min.js.map',
},
plugins,
}, {
input: './js/src/base/sort_tables.js',
output: {
file: './js/tables.min.js',
format: 'iife',
sourcemap: true,
sourcemapFile: './js/tables.min.js.map',
},
plugins,
}];

View File

@ -2,10 +2,38 @@
# yarn lockfile v1
"@types/estree@0.0.39":
version "0.0.39"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
"@types/node@*":
version "10.7.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.7.1.tgz#b704d7c259aa40ee052eec678758a68d07132a2e"
acorn-dynamic-import@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278"
dependencies:
acorn "^5.0.0"
acorn-jsx@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e"
dependencies:
acorn "^5.0.3"
acorn@^5.0.0, acorn@^5.0.3, acorn@^5.4.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8"
alphanum-sort@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
amdefine@>=0.0.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
@ -26,6 +54,20 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
arr-diff@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
dependencies:
arr-flatten "^1.0.1"
arr-flatten@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
array-unique@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
autoprefixer@^7.1.1:
version "7.2.6"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.2.6.tgz#256672f86f7c735da849c4f07d008abb056067dc"
@ -67,6 +109,14 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
braces@^1.8.2:
version "1.8.5"
resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
dependencies:
expand-range "^1.8.1"
preserve "^0.2.0"
repeat-element "^1.1.2"
browserslist@^2.0.0, browserslist@^2.11.3:
version "2.11.3"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2"
@ -82,6 +132,23 @@ browserslist@^4.0.0:
electron-to-chromium "^1.3.52"
node-releases "^1.0.0-alpha.10"
buble@^0.19.2:
version "0.19.3"
resolved "https://registry.yarnpkg.com/buble/-/buble-0.19.3.tgz#01e9412062cff1da6f20342b6ecd72e7bf699d02"
dependencies:
acorn "^5.4.1"
acorn-dynamic-import "^3.0.0"
acorn-jsx "^4.1.1"
chalk "^2.3.1"
magic-string "^0.22.4"
minimist "^1.2.0"
os-homedir "^1.0.1"
vlq "^1.0.0"
builtin-modules@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
caniuse-api@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-2.0.0.tgz#b1ddb5a5966b16f48dc4998444d4bbc6c7d9d834"
@ -114,7 +181,7 @@ chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
chalk@^2.0.1, chalk@^2.4.1:
chalk@^2.0.1, chalk@^2.3.1, chalk@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
dependencies:
@ -122,10 +189,30 @@ chalk@^2.0.1, chalk@^2.4.1:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
clone-buffer@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58"
clone-stats@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680"
clone@^1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
clone@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
cloneable-readable@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.2.tgz#d591dee4a8f8bc15da43ce97dceeba13d43e2a65"
dependencies:
inherits "^2.0.1"
process-nextick-args "^2.0.0"
readable-stream "^2.3.5"
coa@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.1.tgz#f3f8b0b15073e35d70263fb1042cb2c023db38af"
@ -192,10 +279,28 @@ colors@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
commander@2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.6.0.tgz#9df7e52fb2a0cb0fb89058ee80c3104225f37e1d"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
concurrently@^3.6.1:
version "3.6.1"
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-3.6.1.tgz#2f95baec5c4051294dfbb55b57a3b98a3e2b45ec"
dependencies:
chalk "^2.4.1"
commander "2.6.0"
date-fns "^1.23.0"
lodash "^4.5.1"
read-pkg "^3.0.0"
rx "2.3.24"
spawn-command "^0.0.2-1"
supports-color "^3.2.3"
tree-kill "^1.1.0"
connect-cachify-static@^1.3.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/connect-cachify-static/-/connect-cachify-static-1.6.0.tgz#f97eac98fa0ac6e6fe793fc32565f9ca028e9b38"
@ -210,6 +315,10 @@ core-js@^2.4.0:
version "2.5.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
cosmiconfig@^5.0.0:
version "5.0.5"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.5.tgz#a809e3c2306891ce17ab70359dc8bdf661fe2cd0"
@ -345,6 +454,10 @@ csso@^3.5.0:
dependencies:
css-tree "1.0.0-alpha.29"
date-fns@^1.23.0:
version "1.29.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6"
debug@^2.1.2, debug@~2:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@ -432,12 +545,48 @@ esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
estree-walker@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.2.tgz#d3850be7529c9580d815600b53126515e146dd39"
exec-sh@^0.2.0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36"
dependencies:
merge "^1.2.0"
expand-brackets@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
dependencies:
is-posix-bracket "^0.1.0"
expand-range@^1.8.1:
version "1.8.2"
resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
dependencies:
fill-range "^2.1.0"
extglob@^0.3.1:
version "0.3.2"
resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
dependencies:
is-extglob "^1.0.0"
filename-regex@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
fill-range@^2.1.0:
version "2.2.4"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565"
dependencies:
is-number "^2.1.0"
isobject "^2.0.0"
randomatic "^3.0.0"
repeat-element "^1.1.2"
repeat-string "^1.5.2"
find@~0:
version "0.2.9"
resolved "https://registry.yarnpkg.com/find/-/find-0.2.9.tgz#4b73f1ff9e56ad91b76e716407fe5ffe6554bb8c"
@ -448,6 +597,16 @@ flatten@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
for-in@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
for-own@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce"
dependencies:
for-in "^1.0.1"
foreach@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
@ -456,6 +615,31 @@ function-bind@^1.1.0, function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
glob-base@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
dependencies:
glob-parent "^2.0.0"
is-glob "^2.0.0"
glob-parent@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28"
dependencies:
is-glob "^2.0.0"
google-closure-compiler-js@>20170000:
version "20180610.0.0"
resolved "https://registry.yarnpkg.com/google-closure-compiler-js/-/google-closure-compiler-js-20180610.0.0.tgz#df0dbf39ba3977027db2c1beb244368521c9220b"
dependencies:
minimist "^1.2.0"
vinyl "^2.0.1"
webpack-core "^0.6.8"
graceful-fs@^4.1.2:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
@ -480,6 +664,10 @@ hex-color-regex@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
hosted-git-info@^2.1.4:
version "2.7.1"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047"
hsl-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e"
@ -496,6 +684,10 @@ indexes-of@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
inherits@^2.0.1, inherits@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
is-absolute-url@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
@ -508,6 +700,16 @@ is-arrayish@^0.3.1:
version "0.3.2"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
is-builtin-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
dependencies:
builtin-modules "^1.0.0"
is-callable@^1.1.1, is-callable@^1.1.3:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
@ -531,10 +733,52 @@ is-directory@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
is-dotfile@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1"
is-equal-shallow@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534"
dependencies:
is-primitive "^2.0.0"
is-extendable@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
is-extglob@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
is-glob@^2.0.0, is-glob@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
dependencies:
is-extglob "^1.0.0"
is-number@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
dependencies:
kind-of "^3.0.2"
is-number@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff"
is-obj@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
is-posix-bracket@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
is-primitive@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
is-regex@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
@ -555,10 +799,20 @@ is-symbol@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
isarray@1.0.0, isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
isnumeric@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/isnumeric/-/isnumeric-0.2.0.tgz#a2347ba360de19e33d0ffd590fddf7755cbf2e64"
isobject@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
dependencies:
isarray "1.0.0"
js-base64@^2.1.9:
version "2.4.8"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.8.tgz#57a9b130888f956834aa40c5b165ba59c758f033"
@ -581,6 +835,25 @@ json-parse-better-errors@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
kind-of@^3.0.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
dependencies:
is-buffer "^1.1.5"
kind-of@^6.0.0:
version "6.0.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
load-json-file@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
dependencies:
graceful-fs "^4.1.2"
parse-json "^4.0.0"
pify "^3.0.0"
strip-bom "^3.0.0"
lodash._reinterpolate@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
@ -606,10 +879,24 @@ lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
lodash@^4.5.1:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
magic-string@^0.22.4:
version "0.22.5"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.5.tgz#8e9cf5afddf44385c1da5bc2a6a0dbd10b03657e"
dependencies:
vlq "^0.2.2"
math-expression-evaluator@^1.2.14:
version "1.2.17"
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac"
math-random@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac"
mdn-data@^1.0.0, mdn-data@~1.1.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01"
@ -618,6 +905,24 @@ merge@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da"
micromatch@^2.3.11:
version "2.3.11"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
dependencies:
arr-diff "^2.0.0"
array-unique "^0.2.1"
braces "^1.8.2"
expand-brackets "^0.1.4"
extglob "^0.3.1"
filename-regex "^2.0.0"
is-extglob "^1.0.0"
is-glob "^2.0.1"
kind-of "^3.0.2"
normalize-path "^2.0.1"
object.omit "^2.0.0"
parse-glob "^3.0.4"
regex-cache "^0.4.2"
minimatch@^3.0.0:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
@ -648,6 +953,21 @@ node-releases@^1.0.0-alpha.10:
dependencies:
semver "^5.3.0"
normalize-package-data@^2.3.2:
version "2.4.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f"
dependencies:
hosted-git-info "^2.1.4"
is-builtin-module "^1.0.0"
semver "2 || 3 || 4 || 5"
validate-npm-package-license "^3.0.1"
normalize-path@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
dependencies:
remove-trailing-separator "^1.0.1"
normalize-range@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
@ -677,6 +997,13 @@ object.getownpropertydescriptors@^2.0.3:
define-properties "^1.1.2"
es-abstract "^1.5.1"
object.omit@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
dependencies:
for-own "^0.1.4"
is-extendable "^0.1.1"
object.values@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.0.4.tgz#e524da09b4f66ff05df457546ec72ac99f13069a"
@ -694,6 +1021,19 @@ onecolor@^3.0.4:
version "3.0.5"
resolved "https://registry.yarnpkg.com/onecolor/-/onecolor-3.0.5.tgz#36eff32201379efdf1180fb445e51a8e2425f9f6"
os-homedir@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
parse-glob@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
dependencies:
glob-base "^0.3.0"
is-dotfile "^1.0.0"
is-extglob "^1.0.0"
is-glob "^2.0.0"
parse-json@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
@ -709,10 +1049,20 @@ path-parse@^1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
path-type@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
dependencies:
pify "^3.0.0"
pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
pify@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
pixrem@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pixrem/-/pixrem-4.0.1.tgz#2da4a1de6ec4423c5fc3794e930b81d4490ec686"
@ -1232,16 +1582,52 @@ postcss@^7.0.1:
source-map "^0.6.1"
supports-color "^5.4.0"
preserve@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
process-nextick-args@^2.0.0, process-nextick-args@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
q@^1.1.2:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
randomatic@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.0.tgz#36f2ca708e9e567f5ed2ec01949026d50aa10116"
dependencies:
is-number "^4.0.0"
kind-of "^6.0.0"
math-random "^1.0.1"
read-cache@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774"
dependencies:
pify "^2.3.0"
read-pkg@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
dependencies:
load-json-file "^4.0.0"
normalize-package-data "^2.3.2"
path-type "^3.0.0"
readable-stream@^2.3.5:
version "2.3.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
reduce-css-calc@^1.2.7:
version "1.3.0"
resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716"
@ -1267,6 +1653,28 @@ regenerator-runtime@^0.11.0:
version "0.11.1"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
regex-cache@^0.4.2:
version "0.4.4"
resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd"
dependencies:
is-equal-shallow "^0.1.3"
remove-trailing-separator@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
repeat-element@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
repeat-string@^1.5.2:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
replace-ext@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
resolve@^1.1.7:
version "1.8.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
@ -1289,11 +1697,46 @@ rgba-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"
rollup-plugin-buble@^0.19.2:
version "0.19.2"
resolved "https://registry.yarnpkg.com/rollup-plugin-buble/-/rollup-plugin-buble-0.19.2.tgz#c0590c7d3d475b5ed59f129764ec93710cc6e8dd"
dependencies:
buble "^0.19.2"
rollup-pluginutils "^2.0.1"
rollup-plugin-closure-compiler-js@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/rollup-plugin-closure-compiler-js/-/rollup-plugin-closure-compiler-js-1.0.6.tgz#58e3e31297ad1a532d9114108bc06f2756d72c3d"
dependencies:
google-closure-compiler-js ">20170000"
rollup-pluginutils@^2.0.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.3.1.tgz#760d185ccc237dedc12d7ae48c6bcd127b4892d0"
dependencies:
estree-walker "^0.5.2"
micromatch "^2.3.11"
rollup@^0.64.1:
version "0.64.1"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.64.1.tgz#9188ee368e5fcd43ffbc00ec414e72eeb5de87ba"
dependencies:
"@types/estree" "0.0.39"
"@types/node" "*"
rx@2.3.24:
version "2.3.24"
resolved "https://registry.yarnpkg.com/rx/-/rx-2.3.24.tgz#14f950a4217d7e35daa71bbcbe58eff68ea4b2b7"
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
sax@~1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
semver@^5.3.0:
"semver@2 || 3 || 4 || 5", semver@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
@ -1303,6 +1746,10 @@ simple-swizzle@^0.2.2:
dependencies:
is-arrayish "^0.3.1"
source-list-map@~0.1.7:
version "0.1.8"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106"
source-map@^0.5.3, source-map@^0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
@ -1311,6 +1758,38 @@ source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
source-map@~0.4.1:
version "0.4.4"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
dependencies:
amdefine ">=0.0.4"
spawn-command@^0.0.2-1:
version "0.0.2-1"
resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0"
spdx-correct@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82"
dependencies:
spdx-expression-parse "^3.0.0"
spdx-license-ids "^3.0.0"
spdx-exceptions@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9"
spdx-expression-parse@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0"
dependencies:
spdx-exceptions "^2.1.0"
spdx-license-ids "^3.0.0"
spdx-license-ids@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87"
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
@ -1319,12 +1798,22 @@ stable@~0.1.6:
version "0.1.8"
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
dependencies:
safe-buffer "~5.1.0"
strip-ansi@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
dependencies:
ansi-regex "^2.0.0"
strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
stylehacks@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.0.tgz#64b323951c4a24e5fc7b2ec06c137bf32d155e8a"
@ -1376,6 +1865,10 @@ traverse-chain@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/traverse-chain/-/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1"
tree-kill@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.0.tgz#5846786237b4239014f05db156b643212d4c6f36"
uniq@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
@ -1395,6 +1888,10 @@ unquote@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
util.promisify@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030"
@ -1402,6 +1899,13 @@ util.promisify@~1.0.0:
define-properties "^1.1.2"
object.getownpropertydescriptors "^2.0.3"
validate-npm-package-license@^3.0.1:
version "3.0.4"
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
dependencies:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
vendors@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.2.tgz#7fcb5eef9f5623b156bcea89ec37d63676f21801"
@ -1410,9 +1914,35 @@ viewport-dimensions@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/viewport-dimensions/-/viewport-dimensions-0.2.0.tgz#de740747db5387fd1725f5175e91bac76afdf36c"
vinyl@^2.0.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86"
dependencies:
clone "^2.1.1"
clone-buffer "^1.0.0"
clone-stats "^1.0.0"
cloneable-readable "^1.0.0"
remove-trailing-separator "^1.0.1"
replace-ext "^1.0.0"
vlq@^0.2.2:
version "0.2.3"
resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26"
vlq@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.0.tgz#8101be90843422954c2b13eb27f2f3122bdcc806"
watch@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/watch/-/watch-1.0.2.tgz#340a717bde765726fa0aa07d721e0147a551df0c"
dependencies:
exec-sh "^0.2.0"
minimist "^1.2.0"
webpack-core@^0.6.8:
version "0.6.9"
resolved "https://registry.yarnpkg.com/webpack-core/-/webpack-core-0.6.9.tgz#fc571588c8558da77be9efb6debdc5a3b172bdc2"
dependencies:
source-list-map "~0.1.7"
source-map "~0.4.1"