Compare commits
8 Commits
53462cddc3
...
83f06e5914
Author | SHA1 | Date |
---|---|---|
Florian Hartwich | 83f06e5914 | |
Florian Hartwich | 8c3d944561 | |
Florian Hartwich | ee61271550 | |
Florian Hartwich | eab910d505 | |
Florian Hartwich | 5788f65ce5 | |
Florian Hartwich | 84b19310b6 | |
Florian Hartwich | 2fa616570c | |
Florian Hartwich | a7c57ed17c |
|
@ -1,8 +1,9 @@
|
||||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
# compiled output
|
# compiled output
|
||||||
/dist
|
dist/
|
||||||
/tmp
|
tmp/
|
||||||
|
etc/
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
/node_modules
|
/node_modules
|
||||||
|
|
|
@ -11,5 +11,6 @@ module.exports = {
|
||||||
squads: '/squads',
|
squads: '/squads',
|
||||||
users: '/users',
|
users: '/users',
|
||||||
account: '/account',
|
account: '/account',
|
||||||
request: '/request'
|
request: '/request',
|
||||||
|
wars: '/wars'
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const Schema = mongoose.Schema;
|
||||||
|
|
||||||
|
const PlayerSchema = new Schema({
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
fraction: {
|
||||||
|
type: String,
|
||||||
|
enum: ['BLUFOR', 'OPFOR'],
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
warId: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: 'War',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
kill: {
|
||||||
|
type: Number,
|
||||||
|
get: v => Math.round(v),
|
||||||
|
set: v => Math.round(v),
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
death: {
|
||||||
|
type: Number,
|
||||||
|
get: v => Math.round(v),
|
||||||
|
set: v => Math.round(v),
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
friendlyFire: {
|
||||||
|
type: Number,
|
||||||
|
get: v => Math.round(v),
|
||||||
|
set: v => Math.round(v),
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
respawn: {
|
||||||
|
type: Number,
|
||||||
|
get: v => Math.round(v),
|
||||||
|
set: v => Math.round(v),
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
flagTouch: {
|
||||||
|
type: Number,
|
||||||
|
get: v => Math.round(v),
|
||||||
|
set: v => Math.round(v),
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
collection: 'player',
|
||||||
|
timestamps: {createdAt: 'timestamp'}
|
||||||
|
});
|
||||||
|
// optional more indices
|
||||||
|
PlayerSchema.index({timestamp: 1});
|
||||||
|
|
||||||
|
module.exports = mongoose.model('Player', PlayerSchema);
|
|
@ -0,0 +1,39 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const Schema = mongoose.Schema;
|
||||||
|
|
||||||
|
const WarSchema = new Schema({
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
date: {
|
||||||
|
type: Date,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
ptBlufor: {
|
||||||
|
type: Number,
|
||||||
|
get: v => Math.round(v),
|
||||||
|
set: v => Math.round(v),
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
ptOpfor: {
|
||||||
|
type: Number,
|
||||||
|
get: v => Math.round(v),
|
||||||
|
set: v => Math.round(v),
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
bestPlayerId: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
ref: 'Player',
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
collection: 'war',
|
||||||
|
timestamps: {createdAt: 'timestamp'}
|
||||||
|
});
|
||||||
|
// optional more indices
|
||||||
|
WarSchema.index({timestamp: 1});
|
||||||
|
|
||||||
|
module.exports = mongoose.model('War', WarSchema);
|
File diff suppressed because it is too large
Load Diff
|
@ -25,7 +25,8 @@
|
||||||
"jimp": "^0.2.27",
|
"jimp": "^0.2.27",
|
||||||
"jsonwebtoken": "^7.4.0",
|
"jsonwebtoken": "^7.4.0",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
"mongoose": "^4.3.0",
|
"mkdirp": "^0.5.1",
|
||||||
|
"mongoose": "^4.11.1",
|
||||||
"morgan": "~1.6.1",
|
"morgan": "~1.6.1",
|
||||||
"multer": "^1.3.0",
|
"multer": "^1.3.0",
|
||||||
"node-sha1": "^1.0.1",
|
"node-sha1": "^1.0.1",
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// modules
|
||||||
|
const fs = require('fs');
|
||||||
|
const mkdirp = require("mkdirp");
|
||||||
|
const {exec} = require('child_process');
|
||||||
|
const express = require('express');
|
||||||
|
const multer = require('multer');
|
||||||
|
const storage = multer.memoryStorage();
|
||||||
|
const upload = multer({storage: storage});
|
||||||
|
const logger = require('debug')('cc:squads');
|
||||||
|
|
||||||
|
// HTTP status codes by name
|
||||||
|
const codes = require('./http-codes');
|
||||||
|
|
||||||
|
const apiAuthenticationMiddleware = require('../middleware/auth-middleware');
|
||||||
|
const checkMT = require('../middleware/permission-check').checkMT;
|
||||||
|
const routerHandling = require('../middleware/router-handling');
|
||||||
|
|
||||||
|
// Mongoose Model using mongoDB
|
||||||
|
const WarModel = require('../models/war');
|
||||||
|
const PlayerModel = require('../models/player');
|
||||||
|
|
||||||
|
const wars = express.Router();
|
||||||
|
|
||||||
|
// routes **********************
|
||||||
|
wars.route('/')
|
||||||
|
.get((req, res, next) => {
|
||||||
|
const filter = {};
|
||||||
|
WarModel.find(filter, {}, {sort: {date: 'desc'}}, (err, items) => {
|
||||||
|
if (err) {
|
||||||
|
err.status = codes.servererror;
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
if (items) {
|
||||||
|
res.locals.items = items;
|
||||||
|
} else {
|
||||||
|
res.locals.items = [];
|
||||||
|
}
|
||||||
|
res.locals.processed = true;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
.post(apiAuthenticationMiddleware, checkMT, upload.single('log'), (req, res, next) => {
|
||||||
|
let body = req.body;
|
||||||
|
let parts = body.date.split("-");
|
||||||
|
body.date = new Date(parseInt(parts[0], 10),
|
||||||
|
parseInt(parts[1], 10) - 1,
|
||||||
|
parseInt(parts[2], 10));
|
||||||
|
const war = new WarModel(body);
|
||||||
|
|
||||||
|
if (req.file) {
|
||||||
|
war.save((err, item) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
const folderName = __dirname + '/../resource/logs/' + item._id;
|
||||||
|
mkdirp(folderName, function (err) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
fs.appendFile(folderName + '/war.log', new Buffer(req.file.buffer), (err) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
//TODO: combine run and clean in one script
|
||||||
|
exec(__dirname + '/../war-parser/run.sh ' + folderName + ' ' + item._id, (error, stdout) => {
|
||||||
|
if (error) {
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
let obj = JSON.parse(`${stdout}`);
|
||||||
|
|
||||||
|
PlayerModel.create(obj, function (err) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
exec(__dirname + '/../war-parser/clean.sh /../' + folderName + ' | tee ' + folderName + '/clean.log', (error) => {
|
||||||
|
if (error) {
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
res.status(codes.created);
|
||||||
|
res.locals.items = item;
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const err = new Error('no Logfile provided');
|
||||||
|
err.status = codes.wrongmediasend;
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
.all(
|
||||||
|
routerHandling.httpMethodNotAllowed
|
||||||
|
);
|
||||||
|
|
||||||
|
wars.route('/:id')
|
||||||
|
.get((req, res, next) => {
|
||||||
|
WarModel.findById(req.params.id, (err, item) => {
|
||||||
|
if (err) {
|
||||||
|
err.status = codes.servererror;
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
else if (!item) {
|
||||||
|
err = new Error("item not found");
|
||||||
|
err.status = codes.notfound;
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
PlayerModel.find({warId: item._id}, {}, {sort: {kill: 'desc'}}, (err, items) => {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
const responseObj = item.toObject();
|
||||||
|
responseObj.players = items;
|
||||||
|
res.locals.items = responseObj;
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
.all(
|
||||||
|
routerHandling.httpMethodNotAllowed
|
||||||
|
);
|
||||||
|
|
||||||
|
// this middleware function can be used, if you like or remove it
|
||||||
|
// it looks for object(s) in res.locals.items and if they exist, they are send to the client as json
|
||||||
|
wars.use(routerHandling.emptyResponse);
|
||||||
|
|
||||||
|
module.exports = wars;
|
|
@ -31,6 +31,7 @@ const awardingRouter = require('./routes/awardings');
|
||||||
const requestRouter = require('./routes/request');
|
const requestRouter = require('./routes/request');
|
||||||
const signatureRouter = require('./routes/signatures');
|
const signatureRouter = require('./routes/signatures');
|
||||||
const commandRouter = require('./routes/command');
|
const commandRouter = require('./routes/command');
|
||||||
|
const warRouter = require('./routes/wars');
|
||||||
|
|
||||||
// Configuration ***********************************
|
// Configuration ***********************************
|
||||||
// mongoose promise setup
|
// mongoose promise setup
|
||||||
|
@ -75,6 +76,7 @@ app.use(urls.ranks, rankRouter);
|
||||||
app.use(urls.decorations, decorationRouter);
|
app.use(urls.decorations, decorationRouter);
|
||||||
app.use(urls.request, requestRouter);
|
app.use(urls.request, requestRouter);
|
||||||
app.use(urls.awards, awardingRouter);
|
app.use(urls.awards, awardingRouter);
|
||||||
|
app.use(urls.wars, warRouter);
|
||||||
app.use(urls.command, apiAuthenticationMiddleware, checkAdmin, commandRouter);
|
app.use(urls.command, apiAuthenticationMiddleware, checkAdmin, commandRouter);
|
||||||
app.use(urls.account, apiAuthenticationMiddleware, checkAdmin, accountRouter);
|
app.use(urls.account, apiAuthenticationMiddleware, checkAdmin, accountRouter);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict"
|
"use strict";
|
||||||
|
|
||||||
// modules used for graphic manipulation
|
// modules used for graphic manipulation
|
||||||
const jimp = require('jimp');
|
const jimp = require('jimp');
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
FILE="$1/war.log"
|
||||||
|
|
||||||
|
while IFS='' read -r line || [[ -n "$line" ]]; do
|
||||||
|
case "$line" in
|
||||||
|
*"Budget"* | *"Mission"* | *"Abschuss"* | *"Respawn"* | *"Punkte"*)
|
||||||
|
echo $line;
|
||||||
|
echo ""
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done < ${FILE}
|
||||||
|
|
||||||
|
# Add OPT Scoreboard
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if [[ $line =~ [^[:space:]] ]]; then
|
||||||
|
echo "$line"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
done < <(grep -A 100 Scoreboard ${FILE} )
|
|
@ -0,0 +1,90 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
createScoreboard() {
|
||||||
|
NAME="$1"
|
||||||
|
FILE="$2"
|
||||||
|
WAR_ID="$3"
|
||||||
|
|
||||||
|
KILL=0
|
||||||
|
FF=0
|
||||||
|
DEATH=0
|
||||||
|
RESPAWN=0
|
||||||
|
FLAG=0
|
||||||
|
FRACTION=
|
||||||
|
|
||||||
|
#escape '[' -> somehow escapes all special chars, hah?
|
||||||
|
ESC_NAME=$(echo "$NAME" | sed -r 's/[\[]+/\\[/g')
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
case "$line" in
|
||||||
|
*\(WEST\)[" "]von:[" "]${ESC_NAME}[" "]\(EAST\)* | *\(EAST\)[" "]von:[" "]${ESC_NAME}[" "]\(WEST\)*)
|
||||||
|
((KILL++))
|
||||||
|
;;
|
||||||
|
*\(EAST\)[" "]von:[" "]${ESC_NAME}[" "]\(EAST\)* | *\(WEST\)[" "]von:[" "]${ESC_NAME}[" "]\(WEST\)*)
|
||||||
|
((FF++))
|
||||||
|
;;
|
||||||
|
*${ESC_NAME}[" "]*von:*)
|
||||||
|
((DEATH++))
|
||||||
|
;;
|
||||||
|
*Spieler:*${ESC_NAME}*)
|
||||||
|
((RESPAWN++))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ -z ${FRACTION} && ( "$line" == *${ESC_NAME}[" "]\(WEST\)* || "$line" == *${ESC_NAME}[" "]\(NATO\)* ) ]]; then
|
||||||
|
FRACTION="BLUFOR"
|
||||||
|
fi
|
||||||
|
if [[ -z ${FRACTION} && ( "$line" == *${ESC_NAME}[" "]\(EAST\)* || "$line" == *${ESC_NAME}[" "]\(CSAT\)* ) ]]; then
|
||||||
|
FRACTION="OPFOR"
|
||||||
|
fi
|
||||||
|
done < <(grep -- "${ESC_NAME}" ${FILE})
|
||||||
|
|
||||||
|
printf "\t{\"name\":\"$NAME\", \"fraction\":\"$FRACTION\", \"kill\":${KILL}, \"friendlyFire\":${FF}, \"death\":${DEATH}, \"respawn\":${RESPAWN}, \"flagTouch\":${FLAG}, \"warId\":\"${WAR_ID}\"} "
|
||||||
|
if [[ -z ${4} ]]; then
|
||||||
|
printf ",\n"
|
||||||
|
else
|
||||||
|
printf "\n"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FILE="$1/war.log"
|
||||||
|
WAR_ID="$2"
|
||||||
|
PLAYERS=()
|
||||||
|
|
||||||
|
while IFS='' read -r line || [[ -n "$line" ]]; do
|
||||||
|
if [[ -n $line ]]; then
|
||||||
|
case "$line" in
|
||||||
|
*"TFAR_RadioRequestEvent"*)
|
||||||
|
RES=$(echo "$(grep -oP ':[0-9]+\s\(\K.*?(?=\)\sREMOTE)' <<< "$line")")
|
||||||
|
;;
|
||||||
|
*"Respawn"*)
|
||||||
|
RES=$(echo "$(grep -oP '\|\|\sSpieler:\s\K.*?(?=\s-\sKosten:)' <<< "$line")")
|
||||||
|
;;
|
||||||
|
*"Abschuss"*)
|
||||||
|
RES=$(echo "$(grep -oP '\|\|\s\K.*?(?=\s\((EAST|WEST|CIV))' <<< "$line")")
|
||||||
|
RES1=$(echo "$(grep -oP 'von:\s\K.*?(?=\s\((EAST|WEST|CIV))' <<< "$line")")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ $RES != *"Error: No unit"* && $RES1 != *"Error: No unit"* ]]; then
|
||||||
|
if [[ -n $RES && " ${PLAYERS[*]} " != *" $RES "* ]]; then
|
||||||
|
PLAYERS+=("$RES")
|
||||||
|
fi
|
||||||
|
if [[ -n $RES1 && " ${PLAYERS[*]} " != *" $RES1 "* ]]; then
|
||||||
|
PLAYERS+=("$RES1")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < ${FILE}
|
||||||
|
|
||||||
|
echo "["
|
||||||
|
|
||||||
|
for ((i=0; i<${#PLAYERS[*]}; i++));
|
||||||
|
do
|
||||||
|
if [[ "$((i+1))" -eq "${#PLAYERS[*]}" ]]; then
|
||||||
|
last="true"
|
||||||
|
fi
|
||||||
|
createScoreboard "${PLAYERS[i]}" ${FILE} ${WAR_ID} ${last}
|
||||||
|
done
|
||||||
|
echo "]"
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# array of available collection names
|
# array of available collection names
|
||||||
col=(app_user awarding decoration rank squad user promotion)
|
col=(app_user awarding decoration rank squad user promotion player war)
|
||||||
|
|
||||||
for i in "${col[@]}"
|
for i in "${col[@]}"
|
||||||
do
|
do
|
||||||
|
|
|
@ -0,0 +1,515 @@
|
||||||
|
{
|
||||||
|
"name": "opt-cc",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"dependencies": {
|
||||||
|
"ajv": {
|
||||||
|
"version": "4.11.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
|
||||||
|
"integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"ansi-regex": {
|
||||||
|
"version": "0.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
|
||||||
|
"integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"asn1": {
|
||||||
|
"version": "0.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
|
||||||
|
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"assert-plus": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
|
||||||
|
"integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"asynckit": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"aws-sign2": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
|
||||||
|
"integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"aws4": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
|
||||||
|
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"bcrypt-pbkdf": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"boom": {
|
||||||
|
"version": "2.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
|
||||||
|
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"hoek": {
|
||||||
|
"version": "2.16.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
|
||||||
|
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"caseless": {
|
||||||
|
"version": "0.12.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||||
|
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"chalk": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
|
||||||
|
"integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"supports-color": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
|
||||||
|
"integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"co": {
|
||||||
|
"version": "4.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||||
|
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"combined-stream": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"commander": {
|
||||||
|
"version": "2.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz",
|
||||||
|
"integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"concurrently": {
|
||||||
|
"version": "3.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.5.0.tgz",
|
||||||
|
"integrity": "sha1-jPG3cHppFqeKT/W3e7BN7FSzebI=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"core-js": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz",
|
||||||
|
"integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"cryptiles": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
|
||||||
|
"integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"dashdash": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||||
|
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"assert-plus": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"date-fns": {
|
||||||
|
"version": "1.28.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.28.5.tgz",
|
||||||
|
"integrity": "sha1-JXz8RdMi30XvVlhmWWfuhBzXP68=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"delayed-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"ecc-jsbn": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
|
||||||
|
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"escape-string-regexp": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"extend": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"extsprintf": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"forever-agent": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||||
|
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"form-data": {
|
||||||
|
"version": "2.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
|
||||||
|
"integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"getpass": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||||
|
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"assert-plus": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"har-schema": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"har-validator": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
|
||||||
|
"integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"has-ansi": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
|
||||||
|
"integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"has-flag": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"hawk": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
|
||||||
|
"integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"hoek": {
|
||||||
|
"version": "2.16.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
|
||||||
|
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hoek": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/hoek/-/hoek-4.1.1.tgz",
|
||||||
|
"integrity": "sha1-nMVz/7ore0CPtenCoTeWvpTN3Ok=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"http-signature": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"is-typedarray": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"isemail": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/isemail/-/isemail-2.2.1.tgz",
|
||||||
|
"integrity": "sha1-A1PT2aYpUQgMJiwqoKQrjqjp4qY=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"isstream": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||||
|
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"items": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/items/-/items-2.1.1.tgz",
|
||||||
|
"integrity": "sha1-i9FtnIOxlSneWuoyGsqtp4NkoZg=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"joi": {
|
||||||
|
"version": "9.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/joi/-/joi-9.2.0.tgz",
|
||||||
|
"integrity": "sha1-M4WseQGSEwy+Iw6ALsAskhW7/to=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"jsbn": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||||
|
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"json-schema": {
|
||||||
|
"version": "0.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||||
|
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"json-stable-stringify": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"json-stringify-safe": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||||
|
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"jsonify": {
|
||||||
|
"version": "0.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
|
||||||
|
"integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"jsprim": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz",
|
||||||
|
"integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"assert-plus": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lodash": {
|
||||||
|
"version": "4.17.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||||
|
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mime-db": {
|
||||||
|
"version": "1.27.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz",
|
||||||
|
"integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mime-types": {
|
||||||
|
"version": "2.1.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz",
|
||||||
|
"integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"moment": {
|
||||||
|
"version": "2.18.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz",
|
||||||
|
"integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"oauth-sign": {
|
||||||
|
"version": "0.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
|
||||||
|
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"performance-now": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
|
||||||
|
"integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"punycode": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||||
|
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"qs": {
|
||||||
|
"version": "6.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
|
||||||
|
"integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"request": {
|
||||||
|
"version": "2.81.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
|
||||||
|
"integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"rx": {
|
||||||
|
"version": "2.3.24",
|
||||||
|
"resolved": "https://registry.npmjs.org/rx/-/rx-2.3.24.tgz",
|
||||||
|
"integrity": "sha1-FPlQpCF9fjXapxu8vljv9o6ksrc=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"sntp": {
|
||||||
|
"version": "1.0.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
|
||||||
|
"integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"hoek": {
|
||||||
|
"version": "2.16.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
|
||||||
|
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"spawn-command": {
|
||||||
|
"version": "0.0.2-1",
|
||||||
|
"resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz",
|
||||||
|
"integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"sshpk": {
|
||||||
|
"version": "1.13.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
|
||||||
|
"integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"assert-plus": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stringstream": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
|
||||||
|
"integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"strip-ansi": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
|
||||||
|
"integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "3.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
|
||||||
|
"integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"topo": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz",
|
||||||
|
"integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"tough-cookie": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
|
||||||
|
"integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"tree-kill": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-yWPc8DciiS7FnLpWnpQLcZVNFyk=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"tunnel-agent": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||||
|
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"tweetnacl": {
|
||||||
|
"version": "0.14.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||||
|
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"verror": {
|
||||||
|
"version": "1.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz",
|
||||||
|
"integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"wait-on": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-2.0.2.tgz",
|
||||||
|
"integrity": "sha1-CoT9BwJMb8Joyw6r5YW+IXqvK6o=",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"rx": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
|
||||||
|
"integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,7 @@
|
||||||
"deploy-static": "cd ./static && ng build && ln -s ../api/resource/ ../public/resource",
|
"deploy-static": "cd ./static && ng build && ln -s ../api/resource/ ../public/resource",
|
||||||
"deploy-static-prod": "cd ./static && ng build --env=prod && ln -s ../api/resource/ ../public/resource",
|
"deploy-static-prod": "cd ./static && ng build --env=prod && ln -s ../api/resource/ ../public/resource",
|
||||||
"postinstall": "npm install --prefix ./static && npm install --prefix ./api",
|
"postinstall": "npm install --prefix ./static && npm install --prefix ./api",
|
||||||
"mongodb": "mongod --dbpath ./mongodb-data",
|
"mongodb": "mkdir -p mongodb-data && mongod --dbpath ./mongodb-data",
|
||||||
"test": "npm test --prefix ./api",
|
"test": "npm test --prefix ./api",
|
||||||
"e2e": "npm run deploy-static && concurrently \"npm run e2e --prefix ./api\" \"wait-on -t 60000 http://localhost:3001/ && npm run e2e --prefix ./static\" --success first --kill-others",
|
"e2e": "npm run deploy-static && concurrently \"npm run e2e --prefix ./api\" \"wait-on -t 60000 http://localhost:3001/ && npm run e2e --prefix ./static\" --success first --kill-others",
|
||||||
"start-e2e": "npm run deploy-static && npm run e2e --prefix ./api",
|
"start-e2e": "npm run deploy-static && npm run e2e --prefix ./api",
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -21,6 +21,18 @@
|
||||||
<li routerLinkActive="active">
|
<li routerLinkActive="active">
|
||||||
<a routerLink='/cc-overview' class="link">Armeeübersicht</a>
|
<a routerLink='/cc-overview' class="link">Armeeübersicht</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
|
||||||
|
aria-expanded="false">
|
||||||
|
Schlacht Statistik
|
||||||
|
<span class="caret"></span>
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li *ngFor="let war of wars">
|
||||||
|
<a [routerLink]="['/cc-wars/' + war._id]">{{war.title}} <small>{{war.date | date: 'dd.MM.yy'}}</small></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
<li *ngIf="loginService.hasPermission(2)" routerLinkActive="active">
|
<li *ngIf="loginService.hasPermission(2)" routerLinkActive="active">
|
||||||
<a routerLink='/cc-users' class="link">Teilnehmer</a>
|
<a routerLink='/cc-users' class="link">Teilnehmer</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -7,6 +7,8 @@ import {
|
||||||
import {LoginService} from './services/login-service/login-service';
|
import {LoginService} from './services/login-service/login-service';
|
||||||
import {Title} from '@angular/platform-browser';
|
import {Title} from '@angular/platform-browser';
|
||||||
import {AUTH_ENABLED} from './app.tokens';
|
import {AUTH_ENABLED} from './app.tokens';
|
||||||
|
import {WarService} from "./services/war-service/war.service";
|
||||||
|
import {War} from "./models/model-interfaces";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
|
@ -17,8 +19,11 @@ export class AppComponent {
|
||||||
|
|
||||||
defaultTitle: string;
|
defaultTitle: string;
|
||||||
|
|
||||||
|
wars: War[] = [];
|
||||||
|
|
||||||
constructor(@Optional() @Inject(AUTH_ENABLED) public authEnabled,
|
constructor(@Optional() @Inject(AUTH_ENABLED) public authEnabled,
|
||||||
private loginService: LoginService,
|
private loginService: LoginService,
|
||||||
|
private warService: WarService,
|
||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private titleService: Title) {
|
private titleService: Title) {
|
||||||
|
@ -31,7 +36,11 @@ export class AppComponent {
|
||||||
.filter(event => event instanceof NavigationEnd)
|
.filter(event => event instanceof NavigationEnd)
|
||||||
.subscribe(event => {
|
.subscribe(event => {
|
||||||
this.setBrowserTitle();
|
this.setBrowserTitle();
|
||||||
})
|
});
|
||||||
|
this.warService.getAllWars().subscribe((wars) => {
|
||||||
|
this.wars = wars;
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setBrowserTitle() {
|
setBrowserTitle() {
|
||||||
|
|
|
@ -14,5 +14,6 @@ export class AppConfig {
|
||||||
public readonly apiOverviewPath = '/overview';
|
public readonly apiOverviewPath = '/overview';
|
||||||
public readonly apiRequestAwardPath = '/request/award';
|
public readonly apiRequestAwardPath = '/request/award';
|
||||||
public readonly apiPromotionPath = '/request/promotion';
|
public readonly apiPromotionPath = '/request/promotion';
|
||||||
|
public readonly apiWarPath = '/wars';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import {AppUserService} from "./services/app-user-service/app-user.service";
|
||||||
import {AppUserStore} from "./services/stores/app-user.store";
|
import {AppUserStore} from "./services/stores/app-user.store";
|
||||||
import {PromotionService} from "./services/promotion-service/promotion.service";
|
import {PromotionService} from "./services/promotion-service/promotion.service";
|
||||||
import {FilterRankPipe} from "./filter/filter.pipe";
|
import {FilterRankPipe} from "./filter/filter.pipe";
|
||||||
|
import {WarService} from "./services/war-service/war.service";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [BrowserModule, FormsModule, ReactiveFormsModule, appRouting, HttpModule, ClipboardModule],
|
imports: [BrowserModule, FormsModule, ReactiveFormsModule, appRouting, HttpModule, ClipboardModule],
|
||||||
|
@ -53,6 +54,7 @@ import {FilterRankPipe} from "./filter/filter.pipe";
|
||||||
RankStore,
|
RankStore,
|
||||||
AwardingService,
|
AwardingService,
|
||||||
PromotionService,
|
PromotionService,
|
||||||
|
WarService,
|
||||||
AppConfig,
|
AppConfig,
|
||||||
Title,
|
Title,
|
||||||
routingProviders,
|
routingProviders,
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {RequestAwardComponent} from "./request/award/req-award.component";
|
||||||
import {RequestPromotionComponent} from "./request/promotion/req-promotion.component";
|
import {RequestPromotionComponent} from "./request/promotion/req-promotion.component";
|
||||||
import {ConfirmPromotionComponent} from "./request/confirm-promotion/confirm-promotion.component";
|
import {ConfirmPromotionComponent} from "./request/confirm-promotion/confirm-promotion.component";
|
||||||
import {ConfirmAwardComponent} from "./request/confirm-award/confirm-award.component";
|
import {ConfirmAwardComponent} from "./request/confirm-award/confirm-award.component";
|
||||||
|
import {WarDetailComponent} from "./wars/war-detail.component";
|
||||||
|
|
||||||
|
|
||||||
export const appRoutes: Routes = [
|
export const appRoutes: Routes = [
|
||||||
|
@ -20,6 +21,8 @@ export const appRoutes: Routes = [
|
||||||
{path: 'cc-overview', children: armyRoutes},
|
{path: 'cc-overview', children: armyRoutes},
|
||||||
{path: '', redirectTo: '/cc-overview', pathMatch: 'full'},
|
{path: '', redirectTo: '/cc-overview', pathMatch: 'full'},
|
||||||
|
|
||||||
|
{path: 'cc-wars/:id', component: WarDetailComponent},
|
||||||
|
|
||||||
{path: 'login', component: LoginComponent},
|
{path: 'login', component: LoginComponent},
|
||||||
{path: 'signup', component: SignupComponent},
|
{path: 'signup', component: SignupComponent},
|
||||||
|
|
||||||
|
@ -44,6 +47,6 @@ export const appRouting = RouterModule.forRoot(appRoutes);
|
||||||
|
|
||||||
export const routingComponents = [LoginComponent, SignupComponent, RequestAwardComponent, RequestPromotionComponent, ConfirmAwardComponent,
|
export const routingComponents = [LoginComponent, SignupComponent, RequestAwardComponent, RequestPromotionComponent, ConfirmAwardComponent,
|
||||||
ConfirmPromotionComponent, AdminComponent, ...armyRoutingComponents, NotFoundComponent, ...usersRoutingComponents,
|
ConfirmPromotionComponent, AdminComponent, ...armyRoutingComponents, NotFoundComponent, ...usersRoutingComponents,
|
||||||
...squadsRoutingComponents, ...decorationsRoutingComponents, ...ranksRoutingComponents];
|
...squadsRoutingComponents, ...decorationsRoutingComponents, ...ranksRoutingComponents, WarDetailComponent];
|
||||||
|
|
||||||
export const routingProviders = [LoginGuardHL];
|
export const routingProviders = [LoginGuardHL];
|
||||||
|
|
|
@ -16,6 +16,27 @@ export interface User {
|
||||||
awards?: Award[];
|
awards?: Award[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Player {
|
||||||
|
_id?: string;
|
||||||
|
fraction?: string;
|
||||||
|
name?: string;
|
||||||
|
warId?: War;
|
||||||
|
kill?: number;
|
||||||
|
death?: number;
|
||||||
|
friendlyFire?: number;
|
||||||
|
respawn?: number;
|
||||||
|
flagTouch?: number;
|
||||||
|
}
|
||||||
|
export interface War {
|
||||||
|
_id?: string;
|
||||||
|
title?: string;
|
||||||
|
date?: Date;
|
||||||
|
ptBlufor?: number;
|
||||||
|
ptOpfor?: number;
|
||||||
|
bestPlayerId?: Player;
|
||||||
|
players: Player[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface Squad {
|
export interface Squad {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
import {Injectable} from "@angular/core";
|
||||||
|
import {War} from "../../models/model-interfaces";
|
||||||
|
import {AppConfig} from "../../app.config";
|
||||||
|
import {HttpClient} from "../http-client";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class WarService {
|
||||||
|
|
||||||
|
constructor(private http: HttpClient,
|
||||||
|
private config: AppConfig) {
|
||||||
|
}
|
||||||
|
|
||||||
|
getAllWars() {
|
||||||
|
return this.http.get(this.config.apiUrl + this.config.apiWarPath)
|
||||||
|
.map(res => res.json())
|
||||||
|
}
|
||||||
|
|
||||||
|
getWar(warId: string) {
|
||||||
|
return this.http.get(this.config.apiUrl + this.config.apiWarPath + '/' + warId)
|
||||||
|
.map(res => res.json())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
submitDecoration(war: War, logFile?) {
|
||||||
|
let body;
|
||||||
|
|
||||||
|
if (logFile) {
|
||||||
|
body = new FormData();
|
||||||
|
Object.keys(war).map((objectKey) => {
|
||||||
|
if (war[objectKey] !== undefined) {
|
||||||
|
body.append(objectKey, war[objectKey]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
body.append('log', logFile, logFile.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.http.post(this.config.apiUrl + this.config.apiDecorationPath, body)
|
||||||
|
.map(res => res.json())
|
||||||
|
.do(savedDecoration => {
|
||||||
|
console.log('saved successfully')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
.overview {
|
||||||
|
position: fixed;
|
||||||
|
overflow-y: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
bottom: 20px;
|
||||||
|
width: 100%;
|
||||||
|
padding-left: 50px;
|
||||||
|
padding-top: 70px;
|
||||||
|
margin-left: 10px;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trash {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table {
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
table-layout: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
margin-top: 10px;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-head {
|
||||||
|
background: #222222;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell-outline {
|
||||||
|
outline: 1px solid #D4D4D4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-opfor {
|
||||||
|
color: firebrick;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-blufor {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
<div class="overview" xmlns="http://www.w3.org/1999/html">
|
||||||
|
|
||||||
|
<div style="margin-left: 5%">
|
||||||
|
<h2>{{war.title}} - Schlacht vom {{war.date | date: 'dd.MM.yyyy'}}</h2>
|
||||||
|
<h3 class="pull-left">
|
||||||
|
<h4>Endpunktestand:</h4>
|
||||||
|
<span class="text-blufor" style="font-weight: bold; margin-right: 10px">NATO {{war.ptBlufor}}</span>
|
||||||
|
<span style="font-size: x-large">|</span>
|
||||||
|
<span class="text-opfor" style="font-weight: bold; margin-left: 10px;">{{war.ptOpfor}} CSAT</span>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div style="margin-left: 50%; margin-top:1%">
|
||||||
|
<a class="btn btn-default btn-" style="margin: 20px" target="_blank" href="resource/logs/{{war._id}}/clean.log">Logfile anzeigen</a>
|
||||||
|
<form class="form-group">
|
||||||
|
<label class="radio-inline">
|
||||||
|
<input type="radio" name="fractSelect"
|
||||||
|
[checked]="(fractionRadioSelect == undefined) ? 'true' : 'false'"
|
||||||
|
[(ngModel)]="fractionRadioSelect"
|
||||||
|
(change)="filterPlayersByFraction()">Alle
|
||||||
|
</label>
|
||||||
|
<label class="radio-inline">
|
||||||
|
<input type="radio" name="fractSelect" value="BLUFOR"
|
||||||
|
[(ngModel)]="fractionRadioSelect"
|
||||||
|
#fractRadioBufor
|
||||||
|
(change)="filterPlayersByFraction(fractRadioBufor.value)">NATO
|
||||||
|
</label>
|
||||||
|
<label class="radio-inline">
|
||||||
|
<input type="radio" name="fractSelect" value="OPFOR"
|
||||||
|
[(ngModel)]="fractionRadioSelect"
|
||||||
|
#fractRadioOpfor
|
||||||
|
(change)="filterPlayersByFraction(fractRadioOpfor.value)">CSAT
|
||||||
|
</label>
|
||||||
|
<br>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pull-left" style="margin-top:20px;">
|
||||||
|
<div class="table-container" style="width: 75%; min-width: 500px">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="table-head">
|
||||||
|
<th class="col-sm-2" style="border-radius: 10px 0 0 0;">Spieler</th>
|
||||||
|
<th class="col-sm-1">Fraktion</th>
|
||||||
|
<th class="col-sm-1">Kills</th>
|
||||||
|
<th class="col-sm-1">FriendlyFire</th>
|
||||||
|
<th class="col-sm-1">Eroberungen</th>
|
||||||
|
<th class="col-sm-1">Tode</th>
|
||||||
|
<th class="col-sm-1" style="border-radius: 0 10px 0 0;">Respawn</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody *ngFor="let player of players">
|
||||||
|
<tr class="cell-outline">
|
||||||
|
<td style="font-weight: bold" [ngClass]="player.fraction === 'BLUFOR' ? 'text-blufor' : 'text-opfor'">
|
||||||
|
{{player.name}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{player.fraction === 'BLUFOR' ? 'NATO' : 'CSAT'}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{player.kill}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{player.friendlyFire}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{player.flagTouch}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{player.death}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{player.respawn}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
|
@ -0,0 +1,46 @@
|
||||||
|
import {Component} from "@angular/core";
|
||||||
|
import {Player, War} from "../models/model-interfaces";
|
||||||
|
import {WarService} from "../services/war-service/war.service";
|
||||||
|
import {ActivatedRoute} from "@angular/router";
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'war-detail',
|
||||||
|
templateUrl: './war-detail.component.html',
|
||||||
|
styleUrls: ['./war-detail.component.css']
|
||||||
|
})
|
||||||
|
export class WarDetailComponent {
|
||||||
|
|
||||||
|
war: War = {players: []};
|
||||||
|
|
||||||
|
players: Player[] = [];
|
||||||
|
|
||||||
|
fractionRadioSelect: string;
|
||||||
|
|
||||||
|
constructor(private route: ActivatedRoute,
|
||||||
|
private warService: WarService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.route.params
|
||||||
|
.map(params => params['id'])
|
||||||
|
.filter(id => id != undefined)
|
||||||
|
.flatMap(id => this.warService.getWar(id))
|
||||||
|
.subscribe(war => {
|
||||||
|
this.war = war;
|
||||||
|
this.players = war.players;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
filterPlayersByFraction(fraction: string) {
|
||||||
|
if (fraction) {
|
||||||
|
this.players = this.war.players.filter((player) => {
|
||||||
|
console.log(player.fraction + " .... " + fraction);
|
||||||
|
return player.fraction === fraction;
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.players = this.war.players;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue