diff --git a/frontend/src/App.css b/frontend/src/App.css index 583fad6..d926b86 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -47,6 +47,14 @@ background: linear-gradient(180deg, rgba(251,251,251,1) 0%, rgba(240,255,255,1) font-size: 64px; } +.error{ + color:rgb(170,0,0); +} + +.success{ + color:green; +} + @keyframes fadein { 0% {opacity:0;} 100% {opacity:1;} @@ -113,33 +121,32 @@ background: linear-gradient(180deg, rgba(251,251,251,1) 0%, rgba(240,255,255,1) -webkit-transition: outline-offset .15s ease-in-out, background-color .15s linear; transition: outline-offset .15s ease-in-out, background-color .15s linear; border:1px solid #92b0b3; } -.files{ position:relative} -.files:after { pointer-events: none; +.uploadicon { pointer-events: none; position: absolute; - top: 140px; + top: 40px; left: 0; width: 50px; right: 0; height: 56px; content: ""; background-image: url(https://image.flaticon.com/icons/png/128/109/109612.png); - display: block; margin: 0 auto; background-size: 100%; background-repeat: no-repeat; + z-index:100; } .color input{ background-color:#f0f0ff;} -.files:before { +.dragText { position: absolute; - bottom: 10px; + top: 160px; left: 0; pointer-events: none; width: 100%; right: 0; height: 72px; content: " or drag it here. "; - display: block; margin: 0 auto; color: #000000; text-transform: capitalize; text-align: center; + z-index:100; } \ No newline at end of file diff --git a/frontend/src/App.js b/frontend/src/App.js index ac5adb9..62bb7c3 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -13,6 +13,7 @@ import { const REMOTE_ADDR = "http://45.33.13.215:4502"; const axios = require('axios'); +axios.defaults.timeout = 180000; function Logo(){ var note_arrow=new Image(); @@ -55,13 +56,7 @@ function Logo(){ draw.font="64px Open Sans Condensed"; var size=draw.measureText("Pr ject") logo.width=size.width - }); - function drawImage(image, x, y, scale, rotation){ - var draw = logo.getContext("2d"); - draw.setTransform(scale, 0, 0, scale, x, y); // sets scale and origin - draw.rotate(rotation); - draw.drawImage(image, -image.width / 2, -image.height / 2); - } + setInterval(()=>{ if (hitrating==-1) { pos[0]-=startpoint[0]/20; @@ -135,7 +130,15 @@ function Logo(){ } timer+=50; timer2-=50; + //p.setSiteCounter(p.siteCounter+1); },50) + },300); + function drawImage(image, x, y, scale, rotation){ + var draw = logo.getContext("2d"); + draw.setTransform(scale, 0, 0, scale, x, y); // sets scale and origin + draw.rotate(rotation); + draw.drawImage(image, -image.width / 2, -image.height / 2); + } return (<> >); @@ -275,33 +278,76 @@ function Rankings(){ ); } -function Submit() { +function Submit(p) { var [file,setFile] = useState(null); + var [fileProcess,setFileProcess] = useState(0); + var [error,setError] = useState(null); + var [success,setSuccess] = useState(null); + var [fileProgress,setFileProgress] = useState(0); var prepFile = (e)=>{ setFile(e.currentTarget.files[0]) + setError(null); } var uploadFile = (e)=>{ + setError(null); + if (!file) {setError("No file selected!");return;} + if (file.type!=="application/x-zip-compressed" && + file.type!=="image/jpeg" && file.type!=="image/png") { + setError("File type is invalid! Please provide a .zip/.jpg/.png file!") + setFileProcess(0) + return; + } const data = new FormData() data.append('file', file) /*data.append("username","sigonasr2"); data.append("authentication_token","sig");*/ - axios.post("http://projectdivar.com/upload", data, {}) + if (!data.has("username") || !data.has("authentication_token")) {setError("Authentication failed!");return;} + + if (file.size>15*1024*1024) { + setError("File size is too large! Max is 15MB! Consider splitting your plays into chunks (Recommended 50 files per zip).");return; + } + //console.log(file) + setFileProcess(1); + + axios.post("http://projectdivar.com/upload", data, { + onUploadProgress: function(progressEvent) { + //console.log(progressEvent) + setFileProgress(Math.round((progressEvent.loaded * 100) / progressEvent.total)) + }}) .then(res => { - console.log(res.statusText) + setSuccess(res.data); + setFileProgress(100) + setFileProcess(0) }) - .catch((err)=>{console.log(err.message)}) + .catch((err)=>{setError(err.message);setFileProgress(0);setFileProcess(0)}) + } + switch (fileProcess) { + default:{ + return ( +
); + } } - - return (); } function App() { diff --git a/server/app.js b/server/app.js index 7d76ce4..76fd15b 100644 --- a/server/app.js +++ b/server/app.js @@ -2,7 +2,7 @@ const express = require('express') const axios = require('axios') const app = express() const port = 4501 -app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`)) +app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`)) const bodyParser = require('body-parser') const { json } = require('body-parser') const Pool = require('pg').Pool @@ -13,9 +13,13 @@ app.use( }) ) const fileUpload = require('express-fileupload'); +const unzipper = require('unzipper'); +const fs = require('fs'); app.use( fileUpload({createParentPath:true, - safeFileNames: true, preserveExtension: true}) + limits: { fileSize: 15 * 1024 * 1024, files: 1 }, + safeFileNames: true, preserveExtension: true, + abortOnLimit:true, uploadTimeout:0}) ) @@ -84,25 +88,89 @@ app.delete('/remove',(req,res)=>{ }) app.post('/upload', function(req, res) { + if (!req.files || Object.keys(req.files).length === 0 || req.body.username===undefined || req.body.authentication_token===undefined) { - return res.status(400).send('No files were uploaded. Invalid parameters.'); + res.status(400).send('No files were uploaded. Invalid parameters.'); + return; } - + let file = req.files.file; + //console.log(file) + + if (file.size>15*1024*1024) { + res.status(400).send("File is too large! Max is 15MB! Consider splitting your plays into chunks (Recommended 50 files per zip).") + return; + } + + if (file.mimetype!=="application/x-zip-compressed" && + file.mimetype!=="image/jpeg" && file.mimetype!=="image/png") { + res.status(400).send('File type is invalid!'); + return; + } var uploads = 0; var userId = -1; var fileLoc = ""; + var count=0; db.query("select uploads,id from users where username=$1",[req.body.username]) .then((data)=>{uploads=data.rows[0].uploads; userId=data.rows[0].id; fileLoc = "files/plays/"+userId+"/"+uploads; return file.mv(fileLoc); }) - .then((data)=>{return db.query("update users set uploads=$1 where username=$2",[Number(uploads)+1,req.body.username])}) - .then((data)=>{return axios.post("http://projectdivar.com/image",{url:"http://projectdivar.com/"+fileLoc,user:req.body.username,auth:req.body.authentication_token})}) - .then((data)=>{res.status(200).send(data.data)}) - .catch((err)=>{res.status(500).send(err.message)}) + .then((data)=>{ + if (file.mimetype!=="application/x-zip-compressed") { + return db.query("update users set uploads=$1 where username=$2",[Number(uploads)+1,req.body.username]) + } else { + //console.log(uploads) + uploads++; + //console.log(uploads) + return {} + }}) + .then((data)=>{ + if (file.mimetype!=="application/x-zip-compressed") { + return axios.post("http://projectdivar.com/image",{url:"http://projectdivar.com/"+fileLoc,user:req.body.username,auth:req.body.authentication_token}) + } else { + //This is a zip file. + var promises = [] + promises.push(new Promise((resolve)=>{ + var stream = fs.createReadStream(fileLoc) + stream + .pipe(unzipper.Parse()) + .on('entry', function (entry) { + const fileName = entry.path; + const type = entry.type; // 'Directory' or 'File' + const size = entry.vars.uncompressedSize; // There is also compressedSize; + if (type=="File" + && (fileName.includes(".jpg") || fileName.includes(".jpeg") || fileName.includes(".png"))) { + promises.push(new Promise((resolve)=>{entry.pipe(fs.createWriteStream("files/plays/"+userId+"/"+uploads++) + .on('finish',()=>{/*console.log("Promise finished!");*/resolve(count++)})) + })) + } else { + entry.autodrain(); + } + }) + .on('finish',()=>{/*console.log("Read finished");*/resolve()}) + })) + return Promise.all(promises) + }}) + .then((data)=>{ + if (file.mimetype!=="application/x-zip-compressed") { + res.status(200).send("Your play has been submitted! Thank you."); + } else { + //console.log(data) + //console.log(uploads)) + fs.unlink(fileLoc,(err)=>{}) + return db.query("update users set uploads=$1 where username=$2",[Number(uploads)+1,req.body.username]) + } + }) + .then((data)=>{ + if (file.mimetype!=="application/x-zip-compressed") { + } else { + res.status(200).send("Submitted "+count+" plays to the submission system. They will be processed shortly! Thank you.") + } + }) + .catch((err)=>{console.log(err.message);res.status(500).send(err.message)}) }); @@ -114,6 +182,10 @@ app.post('/submit', (req, res) => { fail = (req.body.fail=='true'); //console.log("Fail is "+fail+" type:"+typeof(fail)) } + var submitDate = new Date(); + if (req.body.submitDate!==undefined) { + submitDate=req.body.submitDate; + } if (!(req.body.difficulty==="H"||req.body.difficulty==="N"||req.body.difficulty==="E"||req.body.difficulty==="EX"||req.body.difficulty==="EXEX")) {throw new Error("Invalid difficulty!")} @@ -138,7 +210,7 @@ app.post('/submit', (req, res) => { }) .then((data)=>{if(data && data.rows.length>0){songId=data.rows[0].id; return db.query('select rating from songdata where songid=$1 and difficulty=$2 limit 1',[songId,req.body.difficulty])}else{throw new Error("Could not find song.")}}) .then((data)=>{songRating=data.rows[0].rating;return db.query("select id from plays where userid=$1 and score>0 and difficulty=$2 and songid=$3 limit 1",[userId,req.body.difficulty,songId])}) - .then((data)=>{if(data && data.rows.length>0){alreadyPassed=true;/*console.log(data);*/};var score=CalculateSongScore({rating:songRating,cool:req.body.cool,fine:req.body.fine,safe:req.body.safe,sad:req.body.sad,worst:req.body.worst,percent:req.body.percent,difficulty:req.body.difficulty,fail:fail});return db.query("insert into plays(songId,userId,difficulty,cool,fine,safe,sad,worst,percent,date,score,fail,mod,combo,gamescore) values($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) returning *",[songId,userId,req.body.difficulty,req.body.cool,req.body.fine,req.body.safe,req.body.sad,req.body.worst,req.body.percent,new Date(),score,fail,mod,combo,gameScore])}) + .then((data)=>{if(data && data.rows.length>0){alreadyPassed=true;/*console.log(data);*/};var score=CalculateSongScore({rating:songRating,cool:req.body.cool,fine:req.body.fine,safe:req.body.safe,sad:req.body.sad,worst:req.body.worst,percent:req.body.percent,difficulty:req.body.difficulty,fail:fail});return db.query("insert into plays(songId,userId,difficulty,cool,fine,safe,sad,worst,percent,date,score,fail,mod,combo,gamescore) values($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) returning *",[songId,userId,req.body.difficulty,req.body.cool,req.body.fine,req.body.safe,req.body.sad,req.body.worst,req.body.percent,submitDate,score,fail,mod,combo,gameScore])}) .then((data)=>{if(data && data.rows.length>0){ songsubmitdata = data.rows[0]; //console.log(alreadyPassed+" / "+typeof(alreadyPassed)) @@ -163,7 +235,7 @@ CalculateSongScore=(song)=>{ var noteCount=song.cool+song.fine+song.safe+song.sad+song.worst; var comboBreaks=song.safe+song.sad+song.worst; var scoreMult=1; - if(comboBreaks===0){scoreMult=2}else if(song.percent>=95){scoreMult=1.2}else{scoreMult=1} + if (song.fine===0&&song.safe===0&&song.sad===0&&song.worst===0){scoreMult=3}else if(comboBreaks===0){scoreMult=2}else if(song.percent>=95){scoreMult=1.2}else{scoreMult=1} switch (song.difficulty){ case "E":{if(song.percent<30){scoreMult=0}}break; case "N":{if(song.percent<50){scoreMult=0}}break; @@ -174,7 +246,7 @@ CalculateSongScore=(song)=>{ if(song.percent<60){scoreMult=0} } } - var score = ((song.cool*100+song.fine*50+song.safe*10+song.sad*5)/((noteCount)/(noteCount/1000)))*scoreMult + var score = ((song.cool*100+song.fine*50+song.safe*10+song.sad*5)/1000.0)*scoreMult if (scoreMult>0) { score += Math.pow(song.rating,3)/5 } @@ -199,9 +271,9 @@ CalculateRating=(username)=>{ .catch((err)=>{throw new Error(err.message)})*/ return db.query('select id from users where username=$1 limit 1',[username]) .then((data)=>{if(data.rows.length>0){userId=data.rows[0].id;return db.query('select * from songs order by id asc')}else{return 0}}) - .then((data)=>{if(data.rows.length>0){songs=data.rows;return Promise.all(data.rows.map((song)=>{return db.query('select * from plays where userId=$1 and songId=$2 order by score desc limit 100',[userId,song.id]).then((data)=>{if (data.rows.length>0){debugScoreList+=song.name+"\n"; songs[song.id-1].score=data.rows.reduce((sum,play,i)=>{debugScoreList+=" "+(play.score)+" -> "+(play.score*Math.pow(0.2,i))+"\n";/*console.log("Play score:"+play.score+". Sum:"+sum);*/return sum+play.score*Math.pow(0.2,i);},0);debugScoreList+=" "+songs[song.id-1].score+"\n";}})}))}}) - .then(()=>{return songs.sort((a,b)=>{var scorea=(a.score)?a.score:0;var scoreb=(b.score)?b.score:0;return (scorea>scoreb)?-1:1;}).reduce((sum,song,i)=>{if(song.score){debugScoreList+=song.name+": "+song.score+" -> "+(song.score*Math.pow(0.9,i))+"\n";return sum+song.score*Math.pow(0.9,i)}else{return sum}},0);}) - .then((data)=>{/*console.log(debugScoreList);*/return data}) + .then((data)=>{if(data.rows.length>0){songs=data.rows;return Promise.all(data.rows.map((song)=>{return db.query('select * from plays where userId=$1 and songId=$2 and score!=$3 order by score desc limit 100',[userId,song.id,"NaN"]).then((data)=>{if (data.rows.length>0){debugScoreList+=song.name+"\n"; songs[song.id-1].score=data.rows.reduce((sum,play,i)=>{debugScoreList+=" "+(play.score)+" -> "+(play.score*Math.pow(0.2,i))+"";if (i===0 && play.fine+play.safe+play.sad+play.worst===0){songs[play.songid-1].pfc=true;debugScoreList+="+"}else if (i===0 && play.safe+play.sad+play.worst===0){songs[play.songid-1].fc=true;debugScoreList+="*"}debugScoreList+="\n";/*console.log("Play score:"+play.score+". Sum:"+sum);*/return sum+play.score*Math.pow(0.2,i);},0);debugScoreList+=" "+songs[song.id-1].score+"\n";}})}))}}) + .then(()=>{return songs.sort((a,b)=>{var scorea=(a.score)?a.score:0;var scoreb=(b.score)?b.score:0;return (scorea>scoreb)?-1:1;}).reduce((sum,song,i)=>{if(song.score && !isNaN(song.score)){debugScoreList+=song.name+": "+song.score+" -> "+(song.score*Math.pow(0.9,i))+((song.pfc)?("+"+2):(song.fc)?("+"+1):0)+"\n";return sum+song.score*Math.pow(0.9,i)+((song.pfc)?2:(song.fc)?+1:0)}else{return sum}},0);}) + .then((data)=>{console.log(debugScoreList);return data}) } app.get('/songdiffs',(req,res)=>{ diff --git a/server/node_modules/.bin/mkdirp b/server/node_modules/.bin/mkdirp new file mode 120000 index 0000000..017896c --- /dev/null +++ b/server/node_modules/.bin/mkdirp @@ -0,0 +1 @@ +../mkdirp/bin/cmd.js \ No newline at end of file diff --git a/server/node_modules/.bin/rimraf b/server/node_modules/.bin/rimraf new file mode 120000 index 0000000..4cd49a4 --- /dev/null +++ b/server/node_modules/.bin/rimraf @@ -0,0 +1 @@ +../rimraf/bin.js \ No newline at end of file diff --git a/server/node_modules/balanced-match/.npmignore b/server/node_modules/balanced-match/.npmignore new file mode 100644 index 0000000..ae5d8c3 --- /dev/null +++ b/server/node_modules/balanced-match/.npmignore @@ -0,0 +1,5 @@ +test +.gitignore +.travis.yml +Makefile +example.js diff --git a/server/node_modules/balanced-match/LICENSE.md b/server/node_modules/balanced-match/LICENSE.md new file mode 100644 index 0000000..2cdc8e4 --- /dev/null +++ b/server/node_modules/balanced-match/LICENSE.md @@ -0,0 +1,21 @@ +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/server/node_modules/balanced-match/README.md b/server/node_modules/balanced-match/README.md new file mode 100644 index 0000000..08e918c --- /dev/null +++ b/server/node_modules/balanced-match/README.md @@ -0,0 +1,91 @@ +# balanced-match + +Match balanced string pairs, like `{` and `}` or `` and ``. Supports regular expressions as well! + +[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match) +[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match) + +[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match) + +## Example + +Get the first matching pair of braces: + +```js +var balanced = require('balanced-match'); + +console.log(balanced('{', '}', 'pre{in{nested}}post')); +console.log(balanced('{', '}', 'pre{first}between{second}post')); +console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post')); +``` + +The matches are: + +```bash +$ node example.js +{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' } +{ start: 3, + end: 9, + pre: 'pre', + body: 'first', + post: 'between{second}post' } +{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' } +``` + +## API + +### var m = balanced(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +object with those keys: + +* **start** the index of the first match of `a` +* **end** the index of the matching `b` +* **pre** the preamble, `a` and `b` not included +* **body** the match, `a` and `b` not included +* **post** the postscript, `a` and `b` not included + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`. + +### var r = balanced.range(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +array with indexes: `[ , ]`. + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install balanced-match +``` + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/server/node_modules/balanced-match/index.js b/server/node_modules/balanced-match/index.js new file mode 100644 index 0000000..1685a76 --- /dev/null +++ b/server/node_modules/balanced-match/index.js @@ -0,0 +1,59 @@ +'use strict'; +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} diff --git a/server/node_modules/balanced-match/package.json b/server/node_modules/balanced-match/package.json new file mode 100644 index 0000000..8026e21 --- /dev/null +++ b/server/node_modules/balanced-match/package.json @@ -0,0 +1,77 @@ +{ + "_from": "balanced-match@^1.0.0", + "_id": "balanced-match@1.0.0", + "_inBundle": false, + "_integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "_location": "/balanced-match", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "balanced-match@^1.0.0", + "name": "balanced-match", + "escapedName": "balanced-match", + "rawSpec": "^1.0.0", + "saveSpec": null, + "fetchSpec": "^1.0.0" + }, + "_requiredBy": [ + "/brace-expansion" + ], + "_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "_shasum": "89b4d199ab2bee49de164ea02b89ce462d71b767", + "_spec": "balanced-match@^1.0.0", + "_where": "/home/sigonasr2/divar/server/node_modules/brace-expansion", + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/balanced-match/issues" + }, + "bundleDependencies": false, + "dependencies": {}, + "deprecated": false, + "description": "Match balanced character pairs, like \"{\" and \"}\"", + "devDependencies": { + "matcha": "^0.7.0", + "tape": "^4.6.0" + }, + "homepage": "https://github.com/juliangruber/balanced-match", + "keywords": [ + "match", + "regexp", + "test", + "balanced", + "parse" + ], + "license": "MIT", + "main": "index.js", + "name": "balanced-match", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/balanced-match.git" + }, + "scripts": { + "bench": "make bench", + "test": "make test" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "1.0.0" +} diff --git a/server/node_modules/big-integer/BigInteger.d.ts b/server/node_modules/big-integer/BigInteger.d.ts new file mode 100644 index 0000000..53e7b87 --- /dev/null +++ b/server/node_modules/big-integer/BigInteger.d.ts @@ -0,0 +1,2393 @@ +/** + * Type definitions for BigInteger.js + * Definitions by: Tommy Frazier