Updated game script to align with GameDB API on core. Updated license files to match Github repository. (#82)

This commit is contained in:
Flame Sage 2018-05-09 21:43:23 -04:00 committed by GitHub
parent da5e951b3b
commit 1be32e9ef5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 452 additions and 1113 deletions

View File

@ -1,26 +1,18 @@
const fs = require('fs');
const fsextra = require('fs-extra');
const fs = require('fs-extra');
const path = require('path');
const util = require('util');
const logger = require('winston');
const sanitizeHtml = require('sanitize-html');
const request = require('request-promise');
const toml = require('toml');
const tomlify = require('tomlify-j0.4');
const blackfriday = require('./blackfriday.js');
const del = require('delete');
const exec = require('sync-exec');
const fsPathCode = './citra-games-wiki/games';
const fsPathWiki = './citra-games-wiki.wiki';
const fsPathHugoContent = '../../site/content/game';
const fsPathHugoBoxart = '../../site/static/images/game/boxart';
const fsPathHugoIcon = '../../site/static/images/game/icons';
const fsPathHugoScreenshots = '../../site/static/images/screenshots0';
const fsPathHugoSavefiles = '../../site/static/savefiles/';
const fsPathCode = './citra-games-wiki/games'
const fsPathWiki = './citra-games-wiki.wiki'
const fsPathHugoContent = '../../site/content/game'
const fsPathHugoBoxart = '../../site/static/images/game/boxart'
const fsPathHugoIcon = '../../site/static/images/game/icons'
const fsPathHugoScreenshots = '../../site/static/images/screenshots0'
const fsPathHugoSavefiles = '../../site/static/savefiles/'
process.on('unhandledRejection', err => {
logger.error('Unhandled rejection on process.');
@ -30,290 +22,109 @@ process.on('unhandledRejection', err => {
function gitPull(directory, repository) {
if (fs.existsSync(directory)) {
logger.info(`Fetching latest from Github : ${directory}`);
logger.info(`git --git-dir=${directory} pull`);
exec(`git --git-dir=${directory} pull`);
logger.info(`Fetching latest from Github : ${directory}`);
logger.info(`git --git-dir=${directory} pull`);
exec(`git --git-dir=${directory} pull`);
} else {
logger.info(`Cloning repository from Github : ${directory}`);
logger.info(`git clone ${repository}`);
exec(`git clone ${repository}`);
logger.info(`Cloning repository from Github : ${directory}`);
logger.info(`git clone ${repository}`);
exec(`git clone ${repository}`);
}
}
function getDirectories (srcpath) {
return fs.readdirSync(srcpath)
.filter(file => fs.lstatSync(path.join(srcpath, file)).isDirectory())
async function getDirectories(x) {
return fs.readdir(x).filter(file => fs.lstatSync(path.join(x, file)).isDirectory())
}
async function getGithubIssues() {
var results = [];
// Only loop through the first x pages to prevent API limiting.
for (var page = 0; page <= 15; page++) {
let options = {
url: `https://api.github.com/repos/citra-emu/citra/issues?per_page=99&page=${page}`,
headers: { 'User-Agent': 'citrabot' }
};
logger.verbose(`Requesting Github Issue Page ${page}.`);
var body = await request.get(options);
var obj = JSON.parse(body);
if (obj == null || obj.length == 0) {
logger.verbose(`No more Github issues found -- on page ${page}.`);
break;
} else {
results = results.concat(obj);
}
}
return results;
}
async function getTestcases() {
let options = {
url: 'https://api.citra-emu.org/telemetry/testcase/',
headers: { 'User-Agent': 'citrabot' },
};
var body = await request.get(options);
return JSON.parse(body).map(x => {
return {
id: x.id,
title: x.title,
compatibility: x.compatibility.toString(),
date: x.date,
version: x.version,
buildName: x.buildName,
buildDate: x.buildDate,
cpu: x.cpu,
gpu: x.gpu,
os: x.os,
author: x.author
}
});
}
// Fetch game information stored in Github repository.
gitPull('./citra-games-wiki', 'https://github.com/citra-emu/citra-games-wiki.git');
// Fetch game articles stored in Github wiki.
gitPull('./citra-games-wiki.wiki', 'https://github.com/citra-emu/citra-games-wiki.wiki.git');
// Fetch all issues from Github.
var githubIssues = [];
var wikiEntries = {};
var testcases = [];
async function setup() {
githubIssues = await getGithubIssues();
logger.info(`Imported ${githubIssues.length} issues from Github.`);
testcases = await getTestcases();
logger.info(`Obtained ${testcases.length} testcases from Telemetry API.`);
};
setup().then(function() {
async function run() {
// Make sure the output directories in Hugo exist.
[fsPathHugoContent, fsPathHugoBoxart, fsPathHugoIcon, fsPathHugoSavefiles, fsPathHugoScreenshots].forEach(function (path) {
if (fs.existsSync(path) == false) {
logger.info(`Creating Hugo output directory: ${path}`);
fs.mkdirSync(path);
logger.info(`Creating Hugo output directory: ${path}`);
fs.ensureDirSync(path);
}
});
}).then(function() {
// Transform wiki entries to lowercase
const files = fs.readdirSync(fsPathWiki);
logger.info(`Generating wiki database...`);
files.forEach((file) => {
wikiEntries[file.toLowerCase()] = file;
});
// Fetch game files stored in games-wiki repository.
gitPull('./citra-games-wiki', 'https://github.com/citra-emu/citra-games-wiki.git');
// Loop through each game and process it.
getDirectories(fsPathCode).forEach(function(game) {
processGame(game);
});
}).catch(function(err) {
logger.error(err);
process.exit(1);
});
let games = await request.get({ uri: 'https://api.citra-emu.org/gamedb/websiteFeed/', json: true })
await Promise.all(games.map(async (x) => {
try {
logger.info(`Processing game: ${x.id}`);
function processGame(game) {
try {
if (game == '.git' || game == '_validation') { return; }
// Set metadata.
x.date = `${new Date().toISOString()}`
logger.info(`Processing game: ${game}`);
// In Hugo, data keys need to be strings.
x.compatibility = x.compatibility.toString()
// Copy the boxart for the game.
fsextra.copySync(`${fsPathCode}/${game}/boxart.png`, `${fsPathHugoBoxart}/${game}.png`);
x.testcases.forEach(x => x.compatibility = x.compatibility.toString())
// Copy the icon for the game.
fsextra.copySync(`${fsPathCode}/${game}/icon.png`, `${fsPathHugoIcon}/${game}.png`);
// Reverse the testcases so the most recent ones show up top.
x.testcases = x.testcases.reverse()
x.issues = x.issues || []
var model = toml.parse(fs.readFileSync(`${fsPathCode}/${game}/game.dat`, 'utf8'));
let currentDate = new Date();
model.date = `${currentDate.toISOString()}`;
// Copy the boxart for the game.
fs.copySync(`${fsPathCode}/${x.id}/boxart.png`, `${fsPathHugoBoxart}/${x.id}.png`);
// Look up all testcases associated with the Title IDs.
let releases = model.releases.map(y => y.title);
let foundTestcases = testcases.filter(x => {
return releases.includes(x.title);
});
// If no testcases exist in the toml file, create a blank array.
if (!model.testcases) {
model.testcases = [];
}
// Copy the icon for the game.
fs.copySync(`${fsPathCode}/${x.id}/icon.png`, `${fsPathHugoIcon}/${x.id}.png`);
logger.info(`Found ${foundTestcases.length} testcases from telemetry, found ${model.testcases.length} in toml file.`);
model.testcases = model.testcases.concat(foundTestcases);
// Sort the testcases from most recent to least recent.
model.testcases.sort(function(a, b){
// Turn your strings into dates, and then subtract them
// to get a value that is either negative, positive, or zero.
return new Date(b.date) - new Date(a.date);
});
// SHORTCUTS BLOCK
// Parse testcase information out of the dat to reinject as shortcut values.
if (model.testcases == null || model.testcases.length == 0) {
model.compatibility = "99";
model.testcase_date = "2000-01-01";
} else {
let recent = model.testcases[0];
// The displayed compatibility rating is a weighted arithmetic mean of the submitted ratings.
let numerator = 0;
let denominator = 0;
model.testcases.forEach(testcase => {
// Build date is a better metric but testcases from the TOML files only have a submission date.
let weigh_date = new Date(testcase.buildDate == undefined ? testcase.date : testcase.buildDate);
// The test case is weighted on an exponential decay curve such that a test case is half as relevant as each month (30 days) passes.
// The exponent is obtained by dividing the time in millisecond between the current date and date of testing by the number of milliseconds in 30 days.
let weight = Math.pow(.5, (currentDate - weigh_date) / (30 * 1000 * 3600 * 24));
numerator += testcase.compatibility * weight;
denominator += weight;
});
model.compatibility = Math.round(numerator / denominator).toString();
model.testcase_date = recent.date;
}
const toTrim = ["the", "a", "an"];
let trimmedTitle = model.title.toLowerCase();
toTrim.forEach(trim => {
if (trimmedTitle.startsWith(trim + " ")) {
trimmedTitle = trimmedTitle.substr(trim.length + 1);
}
});
let section_id = `${trimmedTitle[0]}`;
if (!section_id.match(/[a-z]+/)) {
section_id = "#";
}
model.section_id = section_id;
// END SHORTCUTS BLOCK
// SAVEFILE BLOCK
var fsPathCodeSavefilesGame = `${fsPathCode}/${game}/savefiles/`;
var fsPathHugoSavefilesGame = `${fsPathHugoSavefiles}/${game}/`;
if (fs.existsSync(fsPathCodeSavefilesGame)) {
// Create the savefile directory for the game.
if (fs.existsSync(fsPathHugoSavefilesGame) == false) {
// SAVEFILE BLOCK
var fsPathCodeSavefilesGame = `${fsPathCode}/${x.id}/savefiles/`;
var fsPathHugoSavefilesGame = `${fsPathHugoSavefiles}/${x.id}/`;
if (fs.existsSync(fsPathCodeSavefilesGame)) {
// Create the savefile directory for the game.
if (fs.existsSync(fsPathHugoSavefilesGame) == false) {
fs.mkdirSync(fsPathHugoSavefilesGame);
}
// Copy all savefiles into the output folder, and read their data.
fs.readdirSync(fsPathCodeSavefilesGame).forEach(file => {
if (path.extname(file) == '.zip') {
fs.copySync(`${fsPathCodeSavefilesGame}/${file}`, `${fsPathHugoSavefilesGame}/${file}`);
}
});
// Finished copying all savefiles into the output folder, and reading their data.
}
// END SAVEFILE BLOCK
// Copy all savefiles into the output folder, and read their data.
model.savefiles = [];
fs.readdirSync(fsPathCodeSavefilesGame).forEach(file => {
if (path.extname(file) == '.zip') {
fsextra.copySync(`${fsPathCodeSavefilesGame}/${file}`, `${fsPathHugoSavefilesGame}/${file}`);
} else if (path.extname(file) == '.dat') {
// Read the data file into an object.
let savefile = toml.parse(fs.readFileSync(`${fsPathCodeSavefilesGame}/${file}`, 'utf8'));
let stats = fs.statSync(`${fsPathCodeSavefilesGame}/${file}`);
// Store the contents of the file in memory for adding it into the markdown later.
model.savefiles.push({
date: new Date(util.inspect(stats.mtime)),
filename: file.replace('.dat', '.zip'),
title: savefile.title,
description: savefile.description,
author: savefile.author,
title_id: savefile.title_id
});
}
});
// Finished copying all savefiles into the output folder, and reading their data.
}
// END SAVEFILE BLOCK
// GITHUB ISSUES BLOCK
model.issues = [];
model.closed_issues = [];
if (model.github_issues != null && model.github_issues.length > 0) {
model.github_issues.forEach(function(number) {
let issue = githubIssues.find(x => x.number == number);
if (issue == null) {
model.closed_issues.push(number);
} else {
model.issues.push({
number: issue.number.toString(),
title: issue.title,
state: issue.state,
created_at: issue.created_at,
updated_at: issue.updated_at,
labels: issue.labels.map(function(x) { return { name: x.name, color: x.color } })
});
}
});
github_issues = null;
}
// END GITHUB ISSUES BLOCK
// Copy the screenshots for the game.
let fsPathScreenshotInputGame = `${fsPathCode}/${game}/screenshots/`;
let fsPathScreenshotOutputGame = `${fsPathHugoScreenshots}/${game}/`;
if (fs.existsSync(fsPathScreenshotInputGame)) {
// Create the savefile directory for each game.
if (fs.existsSync(fsPathScreenshotOutputGame) == false) {
// Copy the screenshots for the game.
let fsPathScreenshotInputGame = `${fsPathCode}/${x.id}/screenshots/`;
let fsPathScreenshotOutputGame = `${fsPathHugoScreenshots}/${x.id}/`;
if (fs.existsSync(fsPathScreenshotInputGame)) {
// Create the savefile directory for each game.
if (fs.existsSync(fsPathScreenshotOutputGame) == false) {
fs.mkdirSync(fsPathScreenshotOutputGame);
}
// Copy all screenshots into the output folder.
fs.readdirSync(fsPathScreenshotInputGame).forEach(file => {
if (path.extname(file) == '.png') {
fs.copySync(`${fsPathScreenshotInputGame}/${file}`, `${fsPathScreenshotOutputGame}/${file}`);
}
});
}
// Copy all screenshots into the output folder.
fs.readdirSync(fsPathScreenshotInputGame).forEach(file => {
if (path.extname(file) == '.png') {
fsextra.copySync(`${fsPathScreenshotInputGame}/${file}`, `${fsPathScreenshotOutputGame}/${file}`);
}
});
// Clear out the wiki markdown so it won't be stored with the metadata.
let wikiText = x.wiki_markdown
x.wiki_markdown = null
let meta = tomlify(x, null, 2);
let contentOutput = `+++\r\n${meta}\r\n+++\r\n\r\n${wikiText}\r\n`;
await fs.writeFile(`${fsPathHugoContent}/${x.id}.md`, contentOutput);
return x
} catch (ex) {
logger.warn(`${x.id} ${x.title} failed to generate: ${ex}`);
logger.error(ex);
throw ex
}
// WIKI BLOCK
var wikiText = "";
let fsPathWikiGame = `${fsPathWiki}/${wikiEntries[game.toLowerCase() + ".md"]}`;
if (fs.existsSync(fsPathWikiGame)) {
wikiText = fs.readFileSync(fsPathWikiGame, 'utf8');
// Fix Blackfriday markdown rendering differences.
wikiText = blackfriday.fixLists(wikiText);
wikiText = blackfriday.fixLinks(wikiText);
} else {
wikiText = "## No wiki exists yet for this game.";
}
// END WIKI BLOCK
let modelText = tomlify(model, null, 2);
let contentOutput = `+++\r\n${modelText}\r\n+++\r\n\r\n${wikiText}\r\n`;
fs.writeFileSync(`${fsPathHugoContent}/${game}.md`, contentOutput);
} catch (ex) {
logger.warn(`${game} failed to generate: ${ex}`);
logger.error(ex);
}
}))
}
// Script start
run()

View File

@ -1,33 +0,0 @@
// Blackfriday markdown rendering requires a blank line before lists.
module.exports.fixLists = function(markdown) {
var lines = markdown.split(/\r?\n/);
for (var i = 0; i < lines.length; i++) {
// If it's the start of the file, ignore to prevent an index issue.
if (i > lines.length) { return; }
if (i == 0 || lines[i] == '\n') { continue; }
// Search for the start of a list designated by the * character.
if (lines[i].startsWith("* ") && lines[i - 1].startsWith("* ") == false) {
i = i + 1;
lines.splice(i - 1, 0, '');
}
}
return lines.join('\r\n');
}
module.exports.fixLinks = function(markdown) {
let cleaned = markdown;
// Replacing tags like [[Common Issues on Windows|Common Issues]]
cleaned = markdown.replace(/\[\[(.*)\|(.*)\]\]/g, function(match, p1, p2) {
return `[${p1}](${url(p2)})`
});
// Replacing tags like [[Common Issues]]
cleaned = markdown.replace(/\[\[(.*)\]\]/g, function(match, p1) {
return `[${p1}](${url(p1)})`
});
return cleaned;
}

View File

@ -1,23 +1,19 @@
{
"name": "citra-games-wiki",
"name": "citra-games",
"version": "1.0.0",
"description": "Used in Citra Hugo to import Game Wiki articles.",
"description": "Used by Citra to generate markdown articles for GameDb.",
"homepage": "https://citra-emu.org/",
"author": "Flame Sage <chris062689@gmail.com>",
"main": "app.js",
"dependencies": {
"delete": "^0.3.2",
"fs-extra": "^3.0.1",
"request": "^2.81.0",
"request-promise": "^4.2.1",
"rimraf": "^2.6.1",
"sanitize-html": "^1.14.1",
"sync-exec": "^0.6.2",
"toml": "^2.3.2",
"tomlify-j0.4": "^2.0.0",
"winston": "^2.2.0"
},
"preferGlobal": false,
"private": true,
"license": "GPLv3"
"license": "AGPL-3.0-or-later"
}

View File

@ -11,20 +11,6 @@ ajv@^5.1.0:
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
ansi-styles@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
dependencies:
color-convert "^1.9.0"
arr-union@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
array-uniq@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
asn1@~0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
@ -33,14 +19,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
async-array-reduce@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/async-array-reduce/-/async-array-reduce-0.2.1.tgz#c8be010a2b5cd00dea96c81116034693dfdd82d1"
async@^1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
async@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9"
@ -57,17 +35,13 @@ aws4@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
bcrypt-pbkdf@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
dependencies:
tweetnacl "^0.14.3"
bluebird@^3.3.5, bluebird@^3.5.0:
bluebird@^3.5.0:
version "3.5.1"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
@ -83,39 +57,14 @@ boom@5.x.x:
dependencies:
hoek "4.x.x"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
chalk@^2.3.0, chalk@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796"
dependencies:
ansi-styles "^3.2.0"
escape-string-regexp "^1.0.5"
supports-color "^5.2.0"
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
color-convert@^1.9.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed"
dependencies:
color-name "^1.1.1"
color-name@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
colors@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
@ -126,11 +75,7 @@ combined-stream@1.0.6, combined-stream@~1.0.5:
dependencies:
delayed-stream "~1.0.0"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
core-util-is@1.0.2, core-util-is@~1.0.0:
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@ -154,71 +99,12 @@ delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
delete@^0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/delete/-/delete-0.3.2.tgz#7cfecf5ef7dfb802fad27ab8f5be5ae546c5b79e"
dependencies:
async "^1.5.2"
bluebird "^3.3.5"
extend-shallow "^2.0.1"
lazy-cache "^1.0.4"
matched "^0.4.1"
rimraf "^2.5.2"
dom-serializer@0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
dependencies:
domelementtype "~1.1.1"
entities "~1.1.1"
domelementtype@1, domelementtype@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
domelementtype@~1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
domhandler@^2.3.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.1.tgz#892e47000a99be55bbf3774ffea0561d8879c259"
dependencies:
domelementtype "1"
domutils@^1.5.1:
version "1.7.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
dependencies:
dom-serializer "0"
domelementtype "1"
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
dependencies:
jsbn "~0.1.0"
entities@^1.1.1, entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
expand-tilde@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449"
dependencies:
os-homedir "^1.0.1"
extend-shallow@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
dependencies:
is-extendable "^0.1.0"
extend@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
@ -255,10 +141,6 @@ form-data@~2.3.1:
combined-stream "1.0.6"
mime-types "^2.1.12"
fs-exists-sync@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add"
fs-extra@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291"
@ -267,43 +149,12 @@ fs-extra@^3.0.1:
jsonfile "^3.0.0"
universalify "^0.1.0"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
dependencies:
assert-plus "^1.0.0"
glob@^7.0.5:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
global-modules@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d"
dependencies:
global-prefix "^0.1.4"
is-windows "^0.2.0"
global-prefix@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f"
dependencies:
homedir-polyfill "^1.0.0"
ini "^1.3.4"
is-windows "^0.2.0"
which "^1.2.12"
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
@ -319,16 +170,6 @@ har-validator@~5.0.3:
ajv "^5.1.0"
har-schema "^2.0.0"
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
has-glob@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/has-glob/-/has-glob-0.1.1.tgz#a261c4c2a6c667e0c77b700a7f297c39ef3aa589"
dependencies:
is-glob "^2.0.1"
hawk@~6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
@ -342,23 +183,6 @@ hoek@4.x.x:
version "4.2.1"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb"
homedir-polyfill@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc"
dependencies:
parse-passwd "^1.0.0"
htmlparser2@^3.9.0:
version "3.9.2"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"
dependencies:
domelementtype "^1.3.0"
domhandler "^2.3.0"
domutils "^1.5.1"
entities "^1.1.1"
inherits "^2.0.1"
readable-stream "^2.0.2"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
@ -367,59 +191,10 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@^2.0.1, inherits@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
ini@^1.3.4:
version "1.3.5"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
is-extendable@^0.1.0:
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.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-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
is-valid-glob@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe"
is-windows@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c"
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
isstream@0.1.x, isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@ -455,60 +230,10 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
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"
lazy-cache@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
lazy-cache@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264"
dependencies:
set-getter "^0.1.0"
lodash.clonedeep@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
lodash.escaperegexp@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347"
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
lodash.isstring@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
lodash.mergewith@^4.6.0:
version "4.6.1"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927"
lodash@^4.13.1:
version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
matched@^0.4.1:
version "0.4.4"
resolved "https://registry.yarnpkg.com/matched/-/matched-0.4.4.tgz#56d7b7eb18033f0cf9bc52eb2090fac7dc1e89fa"
dependencies:
arr-union "^3.1.0"
async-array-reduce "^0.2.0"
extend-shallow "^2.0.1"
fs-exists-sync "^0.1.0"
glob "^7.0.5"
has-glob "^0.1.1"
is-valid-glob "^0.3.0"
lazy-cache "^2.0.1"
resolve-dir "^0.1.0"
mime-db@~1.33.0:
version "1.33.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
@ -519,54 +244,14 @@ mime-types@^2.1.12, mime-types@~2.1.17:
dependencies:
mime-db "~1.33.0"
minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
brace-expansion "^1.1.7"
number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
dependencies:
wrappy "1"
os-homedir@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
parse-passwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
postcss@^6.0.14:
version "6.0.19"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.19.tgz#76a78386f670b9d9494a655bf23ac012effd1555"
dependencies:
chalk "^2.3.1"
source-map "^0.6.1"
supports-color "^5.2.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"
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
@ -575,18 +260,6 @@ qs@~6.5.1:
version "6.5.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
readable-stream@^2.0.2:
version "2.3.4"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.4.tgz#c946c3f47fa7d8eabc0b6150f4a12f69a4574071"
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.0.3"
util-deprecate "~1.0.1"
request-promise-core@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6"
@ -629,61 +302,16 @@ request@^2.81.0:
tunnel-agent "^0.6.0"
uuid "^3.1.0"
resolve-dir@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e"
dependencies:
expand-tilde "^1.2.2"
global-modules "^0.2.3"
rimraf@^2.5.2, rimraf@^2.6.1:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
dependencies:
glob "^7.0.5"
safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
safe-buffer@^5.0.1, safe-buffer@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
sanitize-html@^1.14.1:
version "1.18.2"
resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.18.2.tgz#61877ba5a910327e42880a28803c2fbafa8e4642"
dependencies:
chalk "^2.3.0"
htmlparser2 "^3.9.0"
lodash.clonedeep "^4.5.0"
lodash.escaperegexp "^4.1.2"
lodash.isplainobject "^4.0.6"
lodash.isstring "^4.0.1"
lodash.mergewith "^4.6.0"
postcss "^6.0.14"
srcset "^1.0.0"
xtend "^4.0.0"
set-getter@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376"
dependencies:
to-object-path "^0.3.0"
sntp@2.x.x:
version "2.1.0"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
dependencies:
hoek "4.x.x"
source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
srcset@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/srcset/-/srcset-1.0.0.tgz#a5669de12b42f3b1d5e83ed03c71046fc48f41ef"
dependencies:
array-uniq "^1.0.2"
number-is-nan "^1.0.0"
sshpk@^1.7.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
@ -706,36 +334,14 @@ stealthy-require@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
string_decoder@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
dependencies:
safe-buffer "~5.1.0"
stringstream@~0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
supports-color@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a"
dependencies:
has-flag "^3.0.0"
sync-exec@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/sync-exec/-/sync-exec-0.6.2.tgz#717d22cc53f0ce1def5594362f3a89a2ebb91105"
to-object-path@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
dependencies:
kind-of "^3.0.2"
toml@^2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.3.tgz#8d683d729577cb286231dfc7a8affe58d31728fb"
tomlify-j0.4@^2.0.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/tomlify-j0.4/-/tomlify-j0.4-2.2.1.tgz#60c4e7dd2066b2e917dd9a0de5fd676c0a6d7c7b"
@ -760,10 +366,6 @@ universalify@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
uuid@^3.1.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
@ -776,12 +378,6 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
which@^1.2.12:
version "1.3.0"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
dependencies:
isexe "^2.0.0"
winston@^2.2.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.0.tgz#808050b93d52661ed9fb6c26b3f0c826708b0aee"
@ -792,11 +388,3 @@ winston@^2.2.0:
eyes "0.1.x"
isstream "0.1.x"
stack-trace "0.0.x"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
xtend@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"

View File

@ -11,5 +11,5 @@
},
"preferGlobal": false,
"private": true,
"license": "GPLv3"
"license": "AGPL-3.0-or-later"
}

View File

@ -14,5 +14,5 @@
},
"preferGlobal": false,
"private": true,
"license": "GPLv3"
"license": "AGPL-3.0-or-later"
}

View File

@ -73,7 +73,7 @@
<td>Title IDs</td>
<td>
{{ range .Params.releases }}
<div><img src="{{ $BaseURL }}/images/regions/{{ .region }}.png" /> {{ .title }}</div>
<div><img src="{{ $BaseURL }}/images/regions/{{ .region }}.png" /> {{ .id }}</div>
{{ end }}
</td>
</tr>
@ -145,7 +145,7 @@
<tbody>
{{- range .Params.issues }}
<tr>
<td><a href="https://github.com/citra-emu/citra/issues/{{ .number }}">{{ .title }}</a></td>
<td><a href="https://github.com/citra-emu/citra/issues/{{ .id }}">{{ .title }}</a></td>
<td>{{ dateFormat "January 2, 2006" .created_at }}</td>
<td>{{ dateFormat "January 2, 2006" .updated_at }}</td>
</tr>

737
yarn.lock

File diff suppressed because it is too large Load Diff