Major refactor for language support, EN, DE, ES, FR, RU

This commit is contained in:
Colin McLeod
2015-08-23 12:38:17 -07:00
parent c7269423ed
commit d596723b7b
75 changed files with 1663 additions and 444 deletions

View File

@@ -62,8 +62,8 @@
<div ui-view="modal" ng-click="bgClicked($event)"></div>
<footer>
<div class="right">
<a href="https://github.com/cmmcleod/coriolis/releases/" target="_blank" title="Coriolis Github Project">Version <%= version %> - <%= date %></a>
<div class="right cap">
<a href="https://github.com/cmmcleod/coriolis/releases/" target="_blank" title="Coriolis Github Project"><span translate="version"></span> <%= version %> - <%= date %></a>
</div>
<div style="max-width:50%" class="l">
Coriolis was created using assets and imagery from Elite: Dangerous, with the permission of Frontier Developments plc, for non-commercial purposes. It is not endorsed by nor reflects the views or opinions of Frontier Developments and no employee of Frontier Developments was involved in the making of it.

View File

@@ -1,6 +1,6 @@
angular.module('app', ['ui.router', 'ct.ui.router.extras.sticky', 'ui.sortable', 'shipyard', 'ngLodash', 'app.templates'])
.run(['$rootScope', '$location', '$window', '$document', '$state', 'commonArray', 'shipSize', 'hardPointClass', 'GroupMap', 'Persist', 'Discounts',
function($rootScope, $location, $window, $doc, $state, CArr, sz, hpc, GroupMap, Persist, Discounts) {
angular.module('app', ['ui.router', 'ct.ui.router.extras.sticky', 'ui.sortable', 'shipyard', 'ngLodash', 'app.templates', 'pascalprecht.translate'])
.run(['$rootScope', '$location', '$window', '$document', '$state', '$translate', 'localeFormat', 'Persist', 'Discounts',
function($rootScope, $location, $window, $doc, $state, $translate, localeFormat, Persist, Discounts) {
// App is running as a standalone web app on tablet/mobile
var isStandAlone;
// This was causing issues on Windows phones ($window.external was causing Angular js to throw an exception). Backup is to try this and set isStandAlone to false if this fails.
@@ -21,7 +21,6 @@ function($rootScope, $location, $window, $doc, $state, CArr, sz, hpc, GroupMap,
$rootScope.prevState = { name: from.name, params: fromParams };
if (to.url) { // Only track states that have a URL
if ($window.ga) {
ga('send', 'pageview', { page: $location.path() });
}
@@ -33,46 +32,57 @@ function($rootScope, $location, $window, $doc, $state, CArr, sz, hpc, GroupMap,
}
});
$rootScope.language = {
opts: {
en: 'English',
de: 'Deutsh',
es: 'Español',
fr: 'Français',
ru: 'ру́сский язы́к'
},
current: Persist.getLangCode()
};
$rootScope.localeFormat = d3.locale(localeFormat.get($rootScope.language.current));
updateNumberFormat();
// Global Reference variables
$rootScope.CArr = CArr;
$rootScope.SZ = sz;
$rootScope.HPC = hpc;
$rootScope.GMAP = GroupMap;
$rootScope.insurance = { opts: [{ name: 'Standard', pct: 0.05 }, { name: 'Alpha', pct: 0.025 }, { name: 'Beta', pct: 0.0375 }] };
$rootScope.insurance = { opts: [{ name: 'standard', pct: 0.05 }, { name: 'alpha', pct: 0.025 }, { name: 'beta', pct: 0.0375 }] };
$rootScope.discounts = { opts: Discounts };
$rootScope.STATUS = ['', 'DISABLED', 'OFF', 'ON'];
$rootScope.STATUS = ['', 'disabled', 'off', 'on'];
$rootScope.STATUS_CLASS = ['', 'disabled', 'warning', 'secondary-disabled'];
$rootScope.title = 'Coriolis';
$rootScope.changeLanguage = function() {
$translate.use($rootScope.language.current);
$rootScope.localeFormat = d3.locale(localeFormat.get($rootScope.language.current));
updateNumberFormat();
$rootScope.$broadcast('languageChanged', $rootScope.language.current);
};
// Formatters
$rootScope.fRPct = d3.format('%');
$rootScope.fTime = function(d) { return Math.floor(d / 60) + ':' + ('00' + Math.floor(d % 60)).substr(-2, 2); };
function updateNumberFormat() {
var locale = $rootScope.localeFormat;
var fGen = $rootScope.fGen = locale.numberFormat('n');
$rootScope.fCrd = locale.numberFormat(',.0f');
$rootScope.fPwr = locale.numberFormat(',.2f');
$rootScope.fRound = function(d) { return fGen(d3.round(d, 2)); };
$rootScope.fPct = locale.numberFormat('.2%');
$rootScope.f1Pct = locale.numberFormat('.1%');
}
/**
* Returns the name of the component mounted in the specified slot
* @param {Object} slot The slot object
* @return {String} The component name
*/
$rootScope.cName = function(slot) {
return slot.c ? slot.c.name ? slot.c.name : GroupMap[slot.c.grp] : null;
return $translate.instant(slot.c ? slot.c.name ? slot.c.name : slot.c.grp : null);
};
// Formatters
$rootScope.fCrd = d3.format(',.0f');
$rootScope.fPwr = d3.format(',.2f');
$rootScope.fRound = function(d) { return d3.round(d, 2); };
$rootScope.fRound4 = function(d) { return d3.round(d, 4); };
$rootScope.fPct = d3.format('.2%');
$rootScope.f1Pct = d3.format('.1%');
$rootScope.fRPct = d3.format('%');
$rootScope.fTime = function(d) { return Math.floor(d / 60) + ':' + ('00' + Math.floor(d % 60)).substr(-2, 2); };
if (isStandAlone) {
var state = Persist.getState();
// If a previous state has been stored, load that state
if (state && state.name && state.params) {
$state.go(state.name, state.params, { location: 'replace' });
} else {
$state.go('shipyard', null, { location: 'replace' }); // Default to home page
}
}
// Global Event Listeners
$doc.bind('keyup', function(e) {
if (e.keyCode == 27) { // Escape Key
@@ -98,4 +108,14 @@ function($rootScope, $location, $window, $doc, $state, CArr, sz, hpc, GroupMap,
}, false);
}
if (isStandAlone) {
var state = Persist.getState();
// If a previous state has been stored, load that state
if (state && state.name && state.params) {
$state.go(state.name, state.params, { location: 'replace' });
} else {
$state.go('shipyard', null, { location: 'replace' }); // Default to home page
}
}
}]);

View File

@@ -1,9 +1,17 @@
/**
* Sets up the routes and handlers before the Angular app is kicked off.
*/
angular.module('app').config(['$provide', '$stateProvider', '$urlRouterProvider', '$locationProvider', 'ShipsDB', function($provide, $stateProvider, $urlRouterProvider, $locationProvider, ships) {
angular.module('app').config(['$provide', '$stateProvider', '$urlRouterProvider', '$locationProvider', '$translateProvider', 'ShipsDB', function($provide, $stateProvider, $urlRouterProvider, $locationProvider, $translateProvider, ships) {
// Use HTML5 push and replace state if possible
$locationProvider.html5Mode({ enabled: true, requireBase: false });
// Use English as default/fallback language
$translateProvider
.useSanitizeValueStrategy('escapeParameters')
.useStorage('Persist')
.fallbackLanguage('en')
.determinePreferredLanguage();
/**
* Set up all states and their routes.
*/

View File

@@ -1,4 +1,4 @@
angular.module('app').controller('ComparisonController', ['lodash', '$rootScope', '$filter', '$scope', '$state', '$stateParams', 'Utils', 'ShipFacets', 'ShipsDB', 'Ship', 'Persist', 'Serializer', function(_, $rootScope, $filter, $scope, $state, $stateParams, Utils, ShipFacets, Ships, Ship, Persist, Serializer) {
angular.module('app').controller('ComparisonController', ['lodash', '$rootScope', '$filter', '$scope', '$state', '$stateParams', '$translate', 'Utils', 'ShipFacets', 'ShipsDB', 'Ship', 'Persist', 'Serializer', function(_, $rootScope, $filter, $scope, $state, $stateParams, $translate, Utils, ShipFacets, Ships, Ship, Persist, Serializer) {
$rootScope.title = 'Coriolis - Compare';
$scope.predicate = 'name'; // Sort by ship name as default
$scope.desc = false;
@@ -155,7 +155,7 @@ angular.module('app').controller('ComparisonController', ['lodash', '$rootScope'
return 'Error - ' + err.statusText;
}
);
$state.go('modal.export', { promise: promise, title: 'Forum BBCode' });
$state.go('modal.export', { promise: promise, title: $translate.instant('FORUM') + ' BBCode' });
};
/**
@@ -184,6 +184,10 @@ angular.module('app').controller('ComparisonController', ['lodash', '$rootScope'
$scope.showBuilds = false;
});
$scope.$on('languageChanged', function() {
$scope.tblUpdate = !$scope.tblUpdate; // Simple switch to trigger the table to update
});
/* Initialization */
if ($scope.compareMode) {
if ($scope.name == 'all') {
@@ -226,7 +230,7 @@ angular.module('app').controller('ComparisonController', ['lodash', '$rootScope'
}
}
// Replace fmt with actual format function as defined in rootScope and retain original index
facets.forEach(function(f, i) { f.fmt = $rootScope[f.fmt]; f.index = i; });
facets.forEach(function(f, i) { f.index = i; });
// Remove default facets, mark as active, and add them back in selected order
_.pullAt(facets, defaultFacets).forEach(function(f) { f.active = true; facets.unshift(f); });
$scope.builds = $filter('orderBy')($scope.builds, $scope.predicate, $scope.desc);

View File

@@ -1,4 +1,4 @@
angular.module('app').controller('OutfitController', ['$window', '$rootScope', '$scope', '$state', '$stateParams', 'ShipsDB', 'Ship', 'Components', 'Serializer', 'Persist', 'calcTotalRange', 'calcSpeed', function($window, $rootScope, $scope, $state, $p, Ships, Ship, Components, Serializer, Persist, calcTotalRange, calcSpeed) {
angular.module('app').controller('OutfitController', ['$window', '$rootScope', '$scope', '$state', '$stateParams', '$translate', 'ShipsDB', 'Ship', 'Components', 'Serializer', 'Persist', 'calcTotalRange', 'calcSpeed', function($window, $rootScope, $scope, $state, $p, $translate, Ships, Ship, Components, Serializer, Persist, calcTotalRange, calcSpeed) {
var win = angular.element($window); // Angularized window object for event triggering
var data = Ships[$p.shipId]; // Retrieve the basic ship properties, slots and defaults
var ship = new Ship($p.shipId, data.properties, data.slots); // Create a new Ship instance
@@ -65,11 +65,11 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
$scope.jrChart = {
labels: {
xAxis: {
title: 'Cargo',
title: 'cargo',
unit: 'T'
},
yAxis: {
title: 'Jump Range',
title: 'jump range',
unit: 'LY'
}
}
@@ -87,11 +87,11 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
$scope.trChart = {
labels: {
xAxis: {
title: 'Cargo',
title: 'cargo',
unit: 'T'
},
yAxis: {
title: 'Total Range',
title: 'total range',
unit: 'LY'
}
}
@@ -110,11 +110,11 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
$scope.speedChart = {
labels: {
xAxis: {
title: 'Cargo',
title: 'cargo',
unit: 'T'
},
yAxis: {
title: 'Speed',
title: 'speed',
unit: 'm/s'
}
}
@@ -258,8 +258,8 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
if ($scope.buildName) {
$state.go('modal.export', {
title: $scope.buildName + ' Export',
description: 'A detailed JSON export of your build for use in other sites and tools',
title: $scope.buildName + ' ' + $translate.instant('export'),
description: $translate.instant('PHRASE_EXPORT_DESC'),
data: Serializer.toDetailedBuild($scope.buildName, ship, $scope.code || Serializer.fromShip(ship))
});
}
@@ -366,15 +366,14 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
function updateRetrofitCosts() {
var costs = $scope.retrofitList = [];
var cName = $rootScope.cName;
var total = 0, i, l, item;
if (ship.bulkheads.id != retrofitShip.bulkheads.id) {
item = {
buyClassRating: ship.bulkheads.c.class + ship.bulkheads.c.rating,
buyName: cName(ship.bulkheads),
buyName: ship.bulkheads.c.name,
sellClassRating: retrofitShip.bulkheads.c.class + retrofitShip.bulkheads.c.rating,
sellName: cName(retrofitShip.bulkheads),
sellName: retrofitShip.bulkheads.c.name,
netCost: ship.bulkheads.discountedCost - retrofitShip.bulkheads.discountedCost
};
costs.push(item);
@@ -388,12 +387,12 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
if (slotGroup[i].id != retroSlotGroup[i].id) {
item = { netCost: 0 };
if (slotGroup[i].id) {
item.buyName = cName(slotGroup[i]);
item.buyName = slotGroup[i].c.name || slotGroup[i].c.grp;
item.buyClassRating = slotGroup[i].c.class + slotGroup[i].c.rating;
item.netCost = slotGroup[i].discountedCost;
}
if (retroSlotGroup[i].id) {
item.sellName = cName(retroSlotGroup[i]);
item.sellName = retroSlotGroup[i].c.name || retroSlotGroup[i].c.grp;
item.sellClassRating = retroSlotGroup[i].c.class + retroSlotGroup[i].c.rating;
item.netCost -= retroSlotGroup[i].discountedCost;
}
@@ -423,6 +422,11 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
$scope.selectedSlot = null;
});
// Hide any open menu/slot/etc if the background is clicked
$scope.$on('languageChanged', function() {
$scope.selectedSlot = null;
});
// Hide any open menu/slot/etc if the background is clicked
$scope.$on('discountChange', function() {
ship.applyDiscounts($rootScope.discounts.ship, $rootScope.discounts.components);

View File

@@ -1,4 +1,4 @@
angular.module('app').directive('areaChart', ['$window', function($window) {
angular.module('app').directive('areaChart', ['$window', '$translate', function($window, $translate) {
return {
restrict: 'A',
scope: {
@@ -47,18 +47,19 @@ angular.module('app').directive('areaChart', ['$window', function($window) {
// Create Y Axis SVG Elements
var yTxt = vis.append('g').attr('class', 'y axis')
.append('text')
.attr('class', 'cap')
.attr('transform', 'rotate(-90)')
.attr('y', -50)
.attr('dy', '.1em')
.style('text-anchor', 'middle')
.text(labels.yAxis.title + ' (' + labels.yAxis.unit + ')');
.text($translate.instant(labels.yAxis.title) + ' (' + $translate.instant(labels.yAxis.unit) + ')');
// Create X Axis SVG Elements
var xLbl = vis.append('g').attr('class', 'x axis');
var xTxt = xLbl.append('text')
.attr('y', 30)
.attr('dy', '.1em')
.style('text-anchor', 'middle')
.text(labels.xAxis.title + ' (' + labels.xAxis.unit + ')');
.text($translate.instant(labels.xAxis.title) + ' (' + $translate.instant(labels.xAxis.unit) + ')');
// Create and Add tooltip
var tip = vis.append('g').style('display', 'none');
@@ -150,8 +151,8 @@ angular.module('app').directive('areaChart', ['$window', function($window) {
tip.attr('transform', 'translate(' + x(x0) + ',' + y(y0) + ')');
tip.selectAll('rect').attr('x', flip ? '-5.75em' : '0.5em').style('text-anchor', flip ? 'end' : 'start');
tip.selectAll('text.label').attr('x', flip ? '-2em' : '1em').style('text-anchor', flip ? 'end' : 'start');
tip.select('text.label.x').text(fmtLong(x0) + ' ' + labels.xAxis.unit);
tip.select('text.label.y').text(fmtLong(y0) + ' ' + labels.yAxis.unit);
tip.select('text.label.x').text(fmtLong(x0) + ' ' + $translate.instant(labels.xAxis.unit));
tip.select('text.label.y').text(fmtLong(y0) + ' ' + $translate.instant(labels.yAxis.unit));
}
scope.$on('$destroy', function() {

View File

@@ -1,4 +1,4 @@
angular.module('app').directive('barChart', ['$window', function($window) {
angular.module('app').directive('barChart', ['$window', '$translate', '$rootScope', function($window, $translate, $rootScope) {
function bName(build) {
return build.buildName + '\n' + build.name;
@@ -25,15 +25,15 @@ angular.module('app').directive('barChart', ['$window', function($window) {
link: function(scope, element) {
var color = d3.scale.ordinal().range([ '#7b6888', '#6b486b', '#3182bd', '#a05d56', '#d0743c']),
labels = scope.facet.lbls,
fmt = scope.facet.fmt,
fmt = null,
unit = null,
properties = scope.facet.props,
unit = scope.facet.unit,
margin = { top: 10, right: 20, bottom: 35, left: 150 },
y0 = d3.scale.ordinal(),
y1 = d3.scale.ordinal(),
x = d3.scale.linear(),
yAxis = d3.svg.axis().scale(y0).outerTickSize(0).orient('left'),
xAxis = d3.svg.axis().scale(x).ticks(5).outerTickSize(0).orient('bottom').tickFormat(d3.format('.2s'));
xAxis = d3.svg.axis().scale(x).ticks(5).outerTickSize(0).orient('bottom');
// Create chart
var svg = d3.select(element[0]).append('svg');
@@ -43,7 +43,7 @@ angular.module('app').directive('barChart', ['$window', function($window) {
var tip = d3.tip()
.attr('class', 'd3-tip')
.html(function(property, propertyIndex) {
return (labels ? (labels[propertyIndex] + ': ') : '') + fmt(property.value) + ' ' + unit;
return (labels ? ($translate.instant(labels[propertyIndex]) + ': ') : '') + fmt(property.value) + ' ' + unit;
});
vis.call(tip);
@@ -53,13 +53,13 @@ angular.module('app').directive('barChart', ['$window', function($window) {
vis.selectAll('g.y.axis g text').each(insertLinebreaks);
// Create X Axis SVG Elements
var xAxisLbl = vis.append('g')
.attr('class', 'x axis')
.attr('class', 'x axis cap')
.append('text')
.attr('y', 30)
.attr('dy', '.1em')
.style('text-anchor', 'middle')
.text(scope.facet.title + (unit ? (' (' + unit + ')') : ''));
.style('text-anchor', 'middle');
updateFormats();
/**
* Watch for changes in the comparison array (ships added/removed, sorting)
@@ -117,6 +117,16 @@ angular.module('app').directive('barChart', ['$window', function($window) {
}
function updateFormats() {
fmt = $rootScope[scope.facet.fmt];
unit = $translate.instant(scope.facet.unit);
xAxisLbl.text($translate.instant(scope.facet.title) + (unit ? (' (' + $translate.instant(unit) + ')') : ''));
xAxis.tickFormat($rootScope.localeFormat.numberFormat('.2s'));
render();
}
scope.$on('languageChanged', updateFormats);
scope.$on('$destroy', function() {
angular.element($window).unbind('orientationchange resize render', render);
tip.destroy(); // Remove the tooltip from the DOM

View File

@@ -1,7 +1,7 @@
angular.module('app').directive('comparisonTable', ['$state', function($state) {
angular.module('app').directive('comparisonTable', ['$state', '$translate', '$rootScope', function($state, $translate, $rootScope) {
function tblHeader(facets) {
var r1 = ['<tr class="main"><th rowspan="2" class="prop" prop="name">Ship</th><th rowspan="2" class="prop" prop="buildName">Build</th>'];
var r1 = ['<tr class="main"><th rowspan="2" class="prop" prop="name">', $translate.instant('SHIP'), '</th><th rowspan="2" class="prop" prop="buildName">', $translate.instant('BUILD'), '</th>'];
var r2 = [];
for (var i = 0, l = facets.length; i < l; i++) {
if (facets[i].active) {
@@ -14,11 +14,11 @@ angular.module('app').directive('comparisonTable', ['$state', function($state) {
r1.push(' prop="', p[0], '" class="prop"');
} else {
for (var j = 0; j < pl; j++) {
r2.push('<th prop="', p[j], '" class="prop ', j === 0 ? 'lft' : '', '">', f.lbls[j], '</th>');
r2.push('<th prop="', p[j], '" class="prop ', j === 0 ? 'lft' : '', '">', $translate.instant(f.lbls[j]), '</th>');
}
}
r1.push('>', f.title, '</th>');
r1.push('>', $translate.instant(f.title), '</th>');
}
}
r1.push('</tr><tr>');
@@ -46,7 +46,7 @@ angular.module('app').directive('comparisonTable', ['$state', function($state) {
var f = facets[j];
var p = f.props;
for (var k = 0, pl = p.length; k < pl; k++) {
body.push('<td>', f.fmt(b[p[k]]), '<u> ', f.unit, '</u></td>');
body.push('<td>', $rootScope[f.fmt](b[p[k]]), '<u> ', $translate.instant(f.unit), '</u></td>');
}
}
}

View File

@@ -1,4 +1,4 @@
angular.module('app').directive('componentSelect', function() {
angular.module('app').directive('componentSelect', ['$translate', function($translate) {
// Generting the HTML in this manner is MUCH faster than using an angular template.
@@ -36,7 +36,7 @@ angular.module('app').directive('componentSelect', function() {
if (o.name) {
list.push(' ' + o.name);
list.push(' ' + $translate.instant(o.name));
}
list.push('</span></li>');
@@ -64,11 +64,11 @@ angular.module('app').directive('componentSelect', function() {
if (groups) {
// At present time slots with grouped options (Hardpoints and Internal) can be empty
list.push('<div class="empty-c" cpid="empty">EMPTY</div>');
list.push('<div class="empty-c upp" cpid="empty">', $translate.instant('empty'), '</div>');
for (var g in groups) {
var grp = groups[g];
var grpCode = grp[Object.keys(grp)[0]].grp; // Nasty operation to get the grp property of the first/any single component
list.push('<div id="', grpCode, '" class="select-group">', g, '</div><ul>');
list.push('<div id="', grpCode, '" class="select-group cap">', $translate.instant(g), '</div><ul>');
appendGroup(list, grp, cid, mass, scope.warning);
list.push('</ul>');
}
@@ -87,4 +87,4 @@ angular.module('app').directive('componentSelect', function() {
}
}
};
});
}]);

View File

@@ -38,9 +38,9 @@ angular.module('app').directive('shipyardHeader', ['lodash', '$rootScope', '$sta
e.stopPropagation();
scope.openedMenu = null;
$state.go('modal.export', {
title: 'Backup',
title: 'backup',
data: Persist.getAll(),
description: 'Backup of all Coriolis data to save or transfer to another browser/device'
description: 'PHRASE_BACKUP_DESC'
});
};
@@ -49,9 +49,9 @@ angular.module('app').directive('shipyardHeader', ['lodash', '$rootScope', '$sta
e.stopPropagation();
scope.openedMenu = null;
$state.go('modal.export', {
title: 'Detailed Export',
title: 'detailed export',
data: Serializer.toDetailedExport(scope.allBuilds),
description: 'Detailed export of all builds for use with other tools and sites'
description: 'PHRASE_EXPORT_DESC'
});
};

View File

@@ -1,4 +1,4 @@
angular.module('app').directive('lineChart', ['$window', function($window) {
angular.module('app').directive('lineChart', ['$window', '$translate', '$rootScope', function($window, $translate, $rootScope) {
return {
restrict: 'A',
scope: {
@@ -12,8 +12,7 @@ angular.module('app').directive('lineChart', ['$window', function($window) {
config = scope.config,
labels = config.labels,
margin = { top: 15, right: 15, bottom: 35, left: 60 },
fmt = d3.format('.3r'),
fmtLong = d3.format('.2f'),
fmtLong = null,
func = seriesConfig.func,
drag = d3.behavior.drag(),
dragging = false,
@@ -21,8 +20,8 @@ angular.module('app').directive('lineChart', ['$window', function($window) {
x = d3.scale.linear(),
y = d3.scale.linear(),
// Define Axes
xAxis = d3.svg.axis().scale(x).outerTickSize(0).orient('bottom').tickFormat(d3.format('.2r')),
yAxis = d3.svg.axis().scale(y).ticks(6).outerTickSize(0).orient('left').tickFormat(fmt),
xAxis = d3.svg.axis().scale(x).outerTickSize(0).orient('bottom'),
yAxis = d3.svg.axis().scale(y).ticks(6).outerTickSize(0).orient('left'),
data = [];
// Create chart
@@ -36,18 +35,20 @@ angular.module('app').directive('lineChart', ['$window', function($window) {
// Create Y Axis SVG Elements
var yTxt = vis.append('g').attr('class', 'y axis')
.append('text')
.attr('class', 'cap')
.attr('transform', 'rotate(-90)')
.attr('y', -50)
.attr('dy', '.1em')
.style('text-anchor', 'middle')
.text(labels.yAxis.title + ' (' + labels.yAxis.unit + ')');
.text($translate.instant(labels.yAxis.title) + ' (' + $translate.instant(labels.yAxis.unit) + ')');
// Create X Axis SVG Elements
var xLbl = vis.append('g').attr('class', 'x axis');
var xTxt = xLbl.append('text')
.attr('class', 'cap')
.attr('y', 30)
.attr('dy', '.1em')
.style('text-anchor', 'middle')
.text(labels.xAxis.title + ' (' + labels.xAxis.unit + ')');
.text($translate.instant(labels.xAxis.title) + ' (' + $translate.instant(labels.xAxis.unit) + ')');
// Create and Add tooltip
var tipWidth = (Math.max(labels.yAxis.unit.length, labels.xAxis.unit.length) * 1.25) + 2;
@@ -72,6 +73,8 @@ angular.module('app').directive('lineChart', ['$window', function($window) {
})
.on('drag', moveTip);
updateFormats();
/**
* Watch for changes in the series data (mass changes, etc)
*/
@@ -177,10 +180,21 @@ angular.module('app').directive('lineChart', ['$window', function($window) {
var tip = tips.selectAll('g.tooltip').attr('transform', function(d, i) { return 'translate(' + x(x0) + ',' + y(series ? y0[series[i]] : y0) + ')'; });
tip.selectAll('rect').attr('x', flip ? (-tipWidth - 0.5) + 'em' : '0.5em').style('text-anchor', flip ? 'end' : 'start');
tip.selectAll('text.label').attr('x', flip ? '-1em' : '1em').style('text-anchor', flip ? 'end' : 'start');
tip.selectAll('text.label.x').text(fmtLong(x0) + ' ' + labels.xAxis.unit);
tips.selectAll('text.label.y').text(function(d, i) { return fmtLong(series ? y0[series[i]] : y0) + ' ' + labels.yAxis.unit; });
tip.selectAll('text.label.x').text(fmtLong(x0) + ' ' + $translate.instant(labels.xAxis.unit));
tips.selectAll('text.label.y').text(function(d, i) { return fmtLong(series ? y0[series[i]] : y0) + ' ' + $translate.instant(labels.yAxis.unit); });
}
function updateFormats() {
xTxt.text($translate.instant(labels.xAxis.title) + ' (' + $translate.instant(labels.xAxis.unit) + ')');
yTxt.text($translate.instant(labels.yAxis.title) + ' (' + $translate.instant(labels.yAxis.unit) + ')');
fmtLong = $rootScope.localeFormat.numberFormat('.2f');
xAxis.tickFormat($rootScope.localeFormat.numberFormat('.2r'));
yAxis.tickFormat($rootScope.localeFormat.numberFormat('.3r'));
render();
}
scope.$on('languageChanged', updateFormats);
scope.$on('$destroy', function() {
angular.element($window).unbind('orientationchange resize render', render);
});

View File

@@ -1,4 +1,4 @@
angular.module('app').directive('powerBands', ['$window', function($window) {
angular.module('app').directive('powerBands', ['$window', '$translate', '$rootScope', function($window, $translate, $rootScope) {
return {
restrict: 'A',
scope: {
@@ -35,16 +35,17 @@ angular.module('app').directive('powerBands', ['$window', function($window) {
// Create Y Axis SVG Elements
vis.append('g').attr('class', 'watt axis');
vis.append('g').attr('class', 'pct axis');
vis.append('text').attr('x', -35).attr('y', 16).attr('class', 'primary').text('RET');
vis.append('text').attr('x', -35).attr('y', barHeight + 18).attr('class', 'primary').text('DEP');
var retLbl = vis.append('text').attr('y', 16);
var depLbl = vis.append('text').attr('y', barHeight + 18);
var retLbl = vis.append('text').attr('x', -35).attr('y', 16).attr('class', 'primary upp');
var depLbl = vis.append('text').attr('x', -35).attr('y', barHeight + 18).attr('class', 'primary upp');
var retVal = vis.append('text').attr('y', 16);
var depVal = vis.append('text').attr('y', barHeight + 18);
// Watch for changes to data and events
scope.$watchCollection('available', render);
angular.element($window).bind('orientationchange resize pwrchange', render);
updateFormats();
function render() {
bands = scope.bands;
@@ -84,8 +85,8 @@ angular.module('app').directive('powerBands', ['$window', function($window) {
}
}
updateLabel(retLbl, w, retBandsSelected, retBandsSelected ? retractedSum : maxBand.retractedSum, available);
updateLabel(depLbl, w, depBandsSelected, depBandsSelected ? deployedSum : maxBand.deployedSum, available);
updateLabel(retVal, w, retBandsSelected, retBandsSelected ? retractedSum : maxBand.retractedSum, available);
updateLabel(depVal, w, depBandsSelected, depBandsSelected ? deployedSum : maxBand.deployedSum, available);
retracted.selectAll('rect').data(bands).enter().append('rect')
.attr('height', barHeight)
@@ -151,6 +152,18 @@ angular.module('app').directive('powerBands', ['$window', function($window) {
return '';
}
function updateFormats() {
retLbl.text($translate.instant('ret'));
depLbl.text($translate.instant('dep'));
wattFmt = $rootScope.localeFormat.numberFormat('.2f');
pctFmt = $rootScope.localeFormat.numberFormat('.1%');
wattAxis.tickFormat($rootScope.localeFormat.numberFormat('.2r'));
pctAxis.tickFormat($rootScope.localeFormat.numberFormat('%'));
render();
}
scope.$on('languageChanged', updateFormats);
scope.$on('$destroy', function() {
angular.element($window).unbind('orientationchange resize pwrchange', render);
});

View File

@@ -3,8 +3,7 @@ angular.module('app').directive('slotHardpoint', ['$rootScope', function($r) {
restrict: 'A',
scope: {
hp: '=',
size: '=',
lbl: '='
size: '='
},
templateUrl: 'views/_slot-hardpoint.html',
link: function(scope) {

View File

@@ -3,7 +3,6 @@ angular.module('app').directive('slotInternal', ['$rootScope', function($r) {
restrict: 'A',
scope: {
c: '=slot',
lbl: '=',
fuel: '='
},
templateUrl: 'views/_slot-internal.html',

View File

@@ -1,7 +1,7 @@
/**
* BBCode Generator functions for embedding in the Elite Dangerous Forums
*/
angular.module('app').factory('Utils', ['$window', '$state', '$http', '$q', function($window, $state, $http, $q) {
angular.module('app').factory('Utils', ['$window', '$state', '$http', '$q', '$translate', '$rootScope', function($window, $state, $http, $q, $translate, $rootScope) {
var shortenAPI = 'https://www.googleapis.com/urlshortener/v1/url?key=';
@@ -24,11 +24,11 @@ angular.module('app').factory('Utils', ['$window', '$state', '$http', '$q', func
p = f.props;
if (p.length == 1) {
l.push('[th][B][COLOR=#FF8C0D]', f.title, '[/COLOR][/B][/th]');
l.push('[th][B][COLOR=#FF8C0D]', $translate.instant(f.title).toUpperCase(), '[/COLOR][/B][/th]');
colCount++;
} else {
for (j = 0; j < p.length; j++) {
l.push('[th][B][COLOR=#FF8C0D]', f.title, '\n', f.lbls[j], '[/COLOR][/B][/th]');
l.push('[th][B][COLOR=#FF8C0D]', $translate.instant(f.title).toUpperCase(), '\n', $translate.instant(f.lbls[j]).toUpperCase(), '[/COLOR][/B][/th]');
colCount++;
}
}
@@ -46,7 +46,7 @@ angular.module('app').factory('Utils', ['$window', '$state', '$http', '$q', func
f = facets[j];
p = f.props;
for (k = 0, pl = p.length; k < pl; k++) {
l.push('[td="align: right"]', f.fmt(b[p[k]]), ' [size=-2]', f.unit, '[/size][/td]');
l.push('[td="align: right"]', $rootScope[f.fmt](b[p[k]]), ' [size=-2]', $translate.instant(f.unit), '[/size][/td]');
}
}
}

235
app/js/i18n/de.js Normal file
View File

@@ -0,0 +1,235 @@
angular.module('app').config(['$translateProvider', 'localeFormatProvider', function($translateProvider, localeFormatProvider) {
// Declare number format settings
localeFormatProvider.addFormat('de', {
decimal: ',',
thousands: '.',
grouping: [3],
currency: ['', ' €'],
dateTime: '%A, der %e. %B %Y, %X',
date: '%d.%m.%Y',
time: '%H:%M:%S',
periods: ['AM', 'PM'], // unused
days: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
shortDays: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
shortMonths: ['Jan', 'Feb', 'Mrz', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
});
$translateProvider.translations('de', {
PHRASE_EXPORT_DESC: 'Ein detaillierter JSON-Export Ihrer Konfiguration für die Verwendung in anderen Websites und Tools',
'A-Rated': 'A-Klasse',
about: 'Über',
action: 'Aktion',
added: 'Hinzugefügt',
Advanced: 'Fortgeschritten',
'Advanced Discovery Scanner': 'Fortgeschrittener Aufklärungsscanner',
agility: 'Beweglichkeit',
alpha: 'Alpha',
ammo: 'Munition',
PHRASE_CONFIRMATION: 'Sind Sie sicher?',
armour: 'Panzerung',
am: 'Automatische Feldwartungseinheit',
available: 'Verfügbar',
backup: 'Sicherungsdatei',
'Basic Discovery Scanner': 'Einfacher Aufklärungsscanner',
bl: 'Strahlenlaser',
beta: 'Beta',
bins: 'Behälter',
boost: 'Boost',
build: 'Konfiguration',
'build name': 'Konfigurationsname',
builds: 'Konfigurationen',
bh: 'Rumpfhüllenverstärkung',
ul: 'Salvenlaser',
buy: 'Kaufen',
cancel: 'Abbrechen',
c: 'Kanone',
capital: 'kapital',
cargo: 'Fracht',
'Cargo Hatch': 'Frachtluke',
cr: 'Frachtgestell',
cs: 'Frachtscanner',
cells: 'Zellen',
'Chaff Launcher': 'Düppel-Werfer',
close: 'Schließen',
cc: 'Krallensteuerung: Sammler',
compare: 'Vergleichen',
'compare all': 'Alles Vergleichen',
comparison: 'Vergleich',
comparisons: 'Vergleiche',
component: 'Komponente',
cost: 'Kostet',
costs: 'Kosten',
cm: 'Gegenmaßnahme',
CR: 'CR',
create: 'Erstellen',
'create new': 'Neu Erstellen',
credits: 'Credits',
Cytoscrambler: 'Zytostreuer',
damage: 'Schaden',
delete: 'Löschen',
'delete all': 'Alles Löschen',
dep: 'ausg',
deployed: 'Ausgefahren',
'detailed export': 'Detailiertes Exportieren',
'Detailed Surface Scanner': 'Detailoberflächenscanner',
disabled: 'Deaktiviert',
discount: 'Rabatt',
Distruptor: 'Disruptor',
dc: 'Standard-Landecomputer',
done: 'Fertig',
DPS: 'DPS',
'edit data': 'Bearbeiten',
efficiency: 'Effizienz',
'Electronic Countermeasure': 'Elektronische Gegenmaßnahme',
empty: 'leer',
Enforcer: 'Vollstrecker',
ENG: 'ANT',
'enter name': 'Namen eingeben',
EPS: 'EPS',
export: 'exportieren',
fixed: 'Fest',
forum: 'Forum',
fc: 'Splitterkanone',
fd: 'Frameshift-Antrieb',
ws: 'Sogwolkenscanner',
FSD: 'FSA',
fi: 'FSA-Unterbrecher',
fuel: 'Treibstoff',
fs: 'Treibstoffsammler',
ft: 'Treibstofftank',
fx: 'Krallensteuerung Treibstoffstransfer',
'full tank': 'Tank voll',
Gimballed: 'Kardanisch',
H: 'R',
hardpoints: 'Waffenaufhängungen',
hb: 'Krallen-Steuereinheit (Ladelukenöffner)',
'Heat Sink Launcher': 'Kühlkörperwerfer',
huge: 'Riesig',
hull: 'Hülle',
hr: 'Rumpfhüllenverstärkung (Paket)',
'Imperial Hammer': 'Imperialer Hammer',
import: 'Importieren',
'import all': 'Alles Importieren',
insurance: 'Versicherung',
'Intermediate Discover Scanner': 'Mittlerer Aufklärungsscanner',
'internal compartments': 'Innenbereichkabine',
'jump range': 'Sprungreichweite',
jumps: 'Sprünge',
kw: 'Tötungsbefehlscanner',
L: 'G',
laden: 'Beladen',
language: 'Sprache',
large: 'Groß',
ls: 'Lebenserhaltung',
'Lightweight Alloy': 'Leichte Legierung',
'lock factor': 'Massensperrefaktor',
LS: 'LS',
LY: 'LJ',
M: 'M',
'm/s': 'M/Sec.',
mass: 'Masse',
max: 'max',
'max mass': 'maximale Masse',
medium: 'Mittel',
'Military Grade Composite': 'Militär-Komposit',
nl: 'Minenwerfer',
'Mining Lance': 'Lanzenabbaulaser',
ml: 'Abbaulaser',
'Mirrored Surface Composite': 'Gespiegelte-Oberfläche-Komposit',
mr: 'Raketenbatterie',
mc: 'Mehrfachgeschütz',
'net cost': 'Nettokosten',
no: 'Nein',
PHRASE_NO_BUILDS: 'Keine Konfigurationen zum Vergleich ausgewählt!',
PHRASE_NO_RETROCH: 'Keine Umrüständerungen',
none: 'Nichts',
'none created': 'Nichts erstellt',
off: 'Aus',
on: 'An',
optimal: 'optimal',
'optimal mass': 'optimale Masse',
'optimize mass': 'Masse optimieren',
overwrite: 'Überschreiben',
Pacifier: 'Friedensstifter',
'Pack-Hound': 'Schwarmwerfer',
PHRASE_IMPORT: 'JSON hier einfügen oder importieren',
pen: 'Durchdr.',
penetration: 'Durchdringung',
permalink: 'Permalink',
pa: 'Plasmabeschleuniger',
'Point Defence': 'Punktverteidigung',
power: 'Energie',
pd: 'Energieverteiler',
pp: 'Kraftwerk',
pri: 'Prio',
priority: 'Priorität',
psg: 'Prismaschildgenerator',
proceed: 'Fortfahren',
pc: 'Krallensteuerung: Erzsucher',
pl: 'Impulslaser',
PWR: 'En.',
rg: 'Schienenkanone',
range: 'Reichweite',
rate: 'Rate',
'Reactive Surface Composite': 'Reaktive-Oberfläche-Komposit',
recharge: 'Aufladen',
rf: 'Raffinerie',
'refuel time': 'Auftankzeit',
'Reinforced Alloy': 'Verstärkte Legierung',
reload: 'Aktualisieren',
rename: 'Umbenennen',
repair: 'Reparieren',
reset: 'Zurücksetzen',
ret: 'Eing',
retracted: 'Eingefahren',
'retrofit costs': 'Nachrüstkosten',
'retrofit from': 'Nachrüsten von',
ROF: 'Kad',
S: 'K',
save: 'Speichern',
sc: 'Scanner',
PHRASE_SELECT_BUILDS: 'Wähle Konfigurationen zum Vergleichen',
sell: 'Verkaufen',
s: 'Sensoren',
settings: 'Konfigurationen',
sb: 'Schildverstärker',
scb: 'Schildzellenbank',
sg: 'Schildgenerator',
shields: 'Schilde',
ship: 'Schiff',
ships: 'Schiffe',
shortened: 'Gekürzt',
size: 'Größe',
skip: 'Überspringen',
small: 'Klein',
speed: 'Geschwindigkeit',
standard: 'Standard',
'Standard Docking Computer': 'Standard-Landecomputer',
Stock: 'Standard',
SYS: 'SYS',
T: 'T',
T_LOAD: 'T-Lad',
'The Retributor': 'Retributor',
t: 'Schubdüsen',
time: 'Dauer',
tp: 'Torpedoaufhängung',
total: 'Gesamt',
'total range': 'Maximale Reichweite',
turret: 'Geschützturm',
type: 'Typ',
U: 'W',
unladen: 'Unbeladen',
PHRASE_UPDATE_RDY: 'Update verfügbar! Klicken zum Aktualisieren',
URL: 'URL',
utility: 'Werkzeug',
'utility mounts': 'Werkzeug-Steckplätze',
version: 'Version',
WEP: 'WAF',
yes: 'Ja',
PHRASE_BACKUP_DESC: 'Sicherung aller Coriolis Daten zu speichern oder auf einen anderen Browser / Gerät'
})
.registerAvailableLanguageKeys(['de'], { 'de_DE': 'de' });
}]);

57
app/js/i18n/en.js Normal file
View File

@@ -0,0 +1,57 @@
angular.module('app').config(['$translateProvider', function($translateProvider) {
$translateProvider
.translations('en', {
am: 'Auto Field-Maintenance Unit',
bl: 'Beam Laser',
bh: 'bulkheads',
ul: 'Burst Laser',
c: 'Cannon',
cr: 'Cargo Rack',
cs: 'Cargo Scanner',
cc: 'Collector Limpet Controller',
cm: 'Countermeasure',
dc: 'Docking Computer',
fc: 'Fragment Cannon',
fd: 'Frame Shift Drive',
ws: 'Frame Shift Wake Scanner',
fi: 'FSD Interdictor',
fs: 'Fuel Scoop',
ft: 'Fuel Tank',
fx: 'Fuel Transfer Limpet Controller',
hb: 'Hatch Breaker Limpet Controller',
hr: 'Hull Reinforcement Package',
kw: 'Kill Warrant Scanner',
ls: 'life support',
nl: 'Mine Launcher',
ml: 'Mining Laser',
mr: 'Missile Rack',
mc: 'Multi-cannon',
pa: 'Plasma Accelerator',
pd: 'power distributor',
pp: 'power plant',
psg: 'Prismatic Shield Generator',
pc: 'Prospector Limpet Controller',
pl: 'Pulse Laser',
rg: 'Rail Gun',
rf: 'Refinery',
sc: 'scanner',
s: 'sensors',
sb: 'Shield Booster',
scb: 'Shield Cell Bank',
sg: 'Shield Generator',
T_LOAD: 't-load',
t: 'thrusters',
tp: 'Torpedo Pylon',
PHRASE_NO_BUILDS: 'No builds added to comparison!',
PHRASE_NO_RETROCH: 'No Retrofitting changes',
PHRASE_IMPORT: 'Paste JSON or import here',
PHRASE_SELECT_BUILDS: 'Select Builds to Compare',
PHRASE_EXPORT_DESC: 'A detailed JSON export of your build for use in other sites and tools',
PHRASE_CONFIRMATION: 'Are You Sure?',
PHRASE_UPDATE_RDY: 'Update Available! Click to Refresh',
PHRASE_BACKUP_DESC: 'Backup of all Coriolis data to save or transfer to another browser/device'
})
.registerAvailableLanguageKeys(['en'], { 'en_US': 'en', 'en_UK': 'en', 'en_GB': 'en', 'en_CA': 'en' });
}]);

265
app/js/i18n/es.js Normal file
View File

@@ -0,0 +1,265 @@
angular.module('app').config(['$translateProvider', 'localeFormatProvider', function($translateProvider, localeFormatProvider) {
// Declare number format settings
localeFormatProvider.addFormat('es', {
decimal: ',',
thousands: '.',
grouping: [3],
currency: ['', ' €'],
dateTime: '%A, %e de %B de %Y, %X',
date: '%d/%m/%Y',
time: '%H:%M:%S',
periods: ['AM', 'PM'],
days: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado'],
shortDays: ['dom', 'lun', 'mar', 'mié', 'jue', 'vie', 'sáb'],
months: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'],
shortMonths: ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic']
});
$translateProvider.translations('es', {
PHRASE_EXPORT_DESC: 'Ein detaillierter JSON-Export Ihrer Konfiguration für die Verwendung in anderen Websites und Tools',
A_RATED: 'A-Klasse',
ABOUT: 'Über',
ACTION: 'Aktion',
ADDED: 'Hinzugefügt',
ADDER: 'Adder',
ADVANCED: 'Fortgeschritten',
'Advanced Discovery Scanner': 'Fortgeschrittener Aufklärungsscanner',
'Advanced Plasma Laser': 'Fortgeschrittener Plasma-Laser',
AGILITY: 'Beweglichkeit',
ALPHA: 'Alpha',
AMMO: 'Munition',
ANACONDA: 'Anaconda',
PHRASE_CONFIRMATION: 'Sind Sie sicher?',
ARMOUR: 'Panzerung',
ASP_EXPLORER: 'Asp Explorer',
am: 'Automatische Feldwartungseinheit',
AVAILABLE: 'Verfügbar',
BACKUP: 'Sicherungsdatei',
'Basic Discovery Scanner': 'Einfacher Aufklärungsscanner',
bl: 'Strahlenlaser',
BELUGA_LINER: 'Beluga Liner',
BETA: 'beta',
BINS: 'Behälter',
BOOST: 'Boost',
BUILD: 'Konfiguration',
BUILD_NAME: 'Konfigurationsname',
BUILDS: 'Konfigurationen',
BULKHEADS: 'Rumpfhüllenverstärkung',
ul: 'Salvenlaser',
BUY: 'Kaufen',
CANCEL: 'Abbrechen',
c: 'Kanone',
CAPITAL: 'kapital',
CARGO: 'Fracht',
CARGO_HATCH: 'Frachtluke',
cr: 'Frachtgestell',
cs: 'Frachtscanner',
CELLS: 'Zellen',
CHAFF_LAUNCHER: 'Düppel-Werfer',
CLOSE: 'Schließen',
COBRA_MK_III: 'Cobra MK III',
COBRA_MK_IV: 'Cobra MK IV',
cc: 'Krallensteuerung: Sammler',
COMPARE: 'Vergleichen',
COMPARE_ALL: 'Alles Vergleichen',
COMPARISON: 'Vergleich',
COMPARISONS: 'Vergleiche',
COMPONENT: 'Komponente',
COST: 'Kostet',
COSTS: 'Kosten',
cm: 'Gegenmaßnahme',
CR: 'CR',
CREATE: 'Erstellen',
CREATE_NEW: 'Neu Erstellen',
CREDITS: 'Credits',
Cytoscrambler: 'Zytostreuer',
DAMAGE: 'Schaden',
DELETE: 'Löschen',
DELETE_ALL: 'Alles Löschen',
DEP: 'Ausg',
DEPLOYED: 'Ausgefahren',
DETAILED_EXPORT: 'Detailiertes Exportieren',
'Detailed Surface Scanner': 'Detailoberflächenscanner',
DIAMONDBACK_EXPLORER: 'Diamondback-Erkunder',
DIAMONDBACK_SCOUT: 'Diamondback-Aufklärer',
DISABLED: 'Deaktiviert',
DISCOUNT: 'Rabatt',
Distruptor: 'Disruptor',
dc: 'Standard-Landecomputer',
DOLPHIN: 'Dolphin',
DONE: 'Fertig',
DPS: 'DPS',
EAGLE: 'Eagle',
EDIT_DATA: 'Bearbeiten',
EFFICIENCY: 'Effizienz',
'Electronic Countermeasure': 'Elektronische Gegenmaßnahme',
EMPTY: 'leer',
ENFORCER: 'Vollstrecker',
ENG: 'FAH',
PHRASE_ENTER_BUILD_NAME: '',
EPS: 'en/s',
EXPORT: 'Exportieren',
FEDERAL_CORVETTE: 'Föderale Korvette',
FEDERAL_DROPSHIP: 'Föderales Abwurfschiff',
FEDERAL_DROPSHIP_MK_II: 'Föderales Abwurfschiff Mk II',
FEDERAL_GUNSHIP: 'Föderales Kanonenschiff',
FER_DE_LANCE: 'Fer-de-Lance',
FIXED: '',
FORUM: 'Forum',
fc: 'Splitterkanone',
fd: 'Frameshift-Antrieb',
ws: 'Sogwolkenscanner',
FSD: 'FSA',
fi: 'FSA-Unterbrecher',
FUEL: 'Treibstoff',
fs: 'Treibstoffsammler',
ft: 'Treibstofftank',
fx: 'Krallensteuerung Treibstoffstransfer',
FULL_TANK: 'Tank voll',
GIMBALLED: 'Kardianisch',
H: 'H',
HARDPOINTS: 'Waffenaufhängungen',
hb: 'Krallen-Steuereinheit (Ladelukenöffner)',
HAULER: 'Hauler',
'Heat Sink Launcher': 'Kühlkörperwerfer',
HUGE: 'Riesig',
HULL: 'Hülle',
hr: 'Rumpfhüllenverstärkung (Paket)',
IMPERIAL_CLIPPER: 'Imperialer Clipper',
IMPERIAL_COURIER: 'Imperialer Kurier',
IMPERIAL_CUTTER: 'Imperialer Cutter',
IMPERIAL_EAGLE: 'Imperialer Eagle',
IMPERIAL_HAMMER: 'Imperialer Hammer',
IMPORT: 'Importieren',
IMPORT_ALL: 'Alles Importieren',
INSURANCE: 'Versicherung',
'Intermediate Discover Scanner': 'Mittlerer Aufklärungsscanner',
INTERNAL_COMPARTMENTS: 'Innenbereichkabine',
JUMP_RANGE: 'Sprungreichweite',
JUMPS: 'Sprünge',
kw: 'Tötungsbefehlscanner',
KRAIT: 'Krait',
L: 'L',
LADEN: 'Beladen',
LANGUAGE: 'Sprache',
LARGE: 'Groß',
ls: 'Lebenserhaltung',
'Lightweight Alloy': 'Leichte Legierung',
LOCK_FACTOR: 'Massensperrefaktor',
LS: 'LS',
LY: 'LJ',
M: 'M',
'm/s': 'M/Sec.',
MASS: 'Masse',
MAX: 'max',
MAX_MASS: 'maximale Masse',
MEDIUM: 'Mittel',
'Military Grade Composite': 'Militär-Komposit',
nl: 'Minenwerfer',
'Mining Lance': 'Lanzenabbaulaser',
ml: 'Abbaulaser',
'Mirrored Surface Composite': 'Gespiegelte-Oberfläche-Komposit',
mr: 'Raketenbatterie',
mc: 'Mehrfachgeschütz',
NET_COST: 'Nettokosten',
NO: 'Nein',
NO_RETROFITTING_CHANGES: 'Keine Umrüständerungen',
NONE: 'Nichts',
NONE_CREATED: 'Nichts erstellt',
OFF: 'Aus',
ON: 'An',
OPTIMAL: 'optimal',
OPTIMAL_MASS: 'optimale Masse',
OPTIMIZE_MASS: 'Masse optimieren',
ORCA: 'Orca',
OVERWRITE: 'Überschreiben',
Pacifier: 'Friedensstifter',
'Pack-Hound': 'Schwarmwerfer',
PANTHER_CLIPPER: 'Panter Clipper',
PHRASE_IMPORT: 'JSON hier einfügen oder hier importieren',
PEN: 'Durchdr',
PENETRATION: 'Durchdringung',
PERMALINK: 'Permalink',
pa: 'Plasmabeschleuniger',
POINT_DEFENCE: 'Punktverteidigung',
POWER: 'Energie',
pd: 'Energieverteiler',
pp: 'Kraftwerk',
PRI: 'Prio',
PRIORITY: 'Priorität',
psg: 'Prismaschildgenerator',
PROCEED: 'Fortfahren',
pc: 'Krallensteuerung: Erzsucher',
pl: 'Impulslaser',
PWR: 'En',
PYTHON: 'Python',
rg: 'Schienenkanone',
RANGE: 'Reichweite',
RATE: 'Rate',
'Reactive Surface Composite': 'Reaktive-Oberfläche-Komposit',
RECHARGE: 'Aufladen',
rf: 'Raffinerie',
REFUEL_TIME: 'Auftankzeit',
'Reinforced Alloy': 'Verstärkte Legierungen',
RELOAD: 'Aktualisieren',
RENAME: 'Umbenennen',
REPAIR: 'Reparieren',
RESET: 'Zurücksetzen',
RET: 'eing',
RETRACTED: 'Eingefahren',
RETROFIT_COSTS: 'Nachrüstkosten',
RETROFIT_FROM: 'Nachrüsten von',
ROF: 'Kad',
S: 'S',
SAVE: 'Speichern',
sc: 'Scanner',
PHRASE_SELECT_BUILDS: 'Wähle Konfigurationen zum Vergleichen',
SELL: 'Verkaufen',
s: 'Sensoren',
SETTINGS: 'Konfiguration',
sb: 'Schildverstärker',
scb: 'Schildzellenbank',
sg: 'Schildgenerator',
SHIELDS: 'Schilde',
SHIP: 'Schiff',
SHIPS: 'Schiffe',
SHORTENED: 'Gekürzt',
SIDEWINDER: 'Sidewinder',
SIZE: 'Größe',
SKIP: 'Überspringen',
SMALL: 'S',
SPEED: 'Geschwindigkeit',
STANDARD: 'Standard',
STANDARD_DOCKING_COMPUTER: 'Landecomputer',
STOCK: 'Standard',
SYS: 'SYS',
T: 'T',
T_LOAD: 'T-Lad',
THE_HUNTER: 'The Hunter',
'The Retributor': 'Retributor',
t: 'Schubdüsen',
TIME: 'Dauer',
tp: 'Torpedoaufhängung',
TOTAL: 'Gesamt',
TOTAL_RANGE: 'Maximale Reichweite',
TURRET: 'Geschützturm',
TYPE: 'Typ',
TYPE_6_TRANSPORTER: 'Typ-6 Transporter',
TYPE_7_TRANSPORTER: 'Typ-7 Transporter',
TYPE_9_HEAVY: 'Typ-9 Transporter (schwer)',
U: 'U',
UNLADEN: 'Unbeladen',
UPDATE_NOTIFICATION: 'Update verfügbar! Klicken zum Aktualisieren',
URL: 'URL',
UTILITY: 'Werkzeug',
UTILITY_MOUNTS: 'Werkzeug-Steckplatz',
VERSION: 'Version',
VIPER: 'Viper',
VULTURE: 'Vulture',
WEP: 'WAF',
YES: 'Ja'
})
.registerAvailableLanguageKeys(['es'], { 'es_ES': 'es' });
}]);

265
app/js/i18n/fr.js Normal file
View File

@@ -0,0 +1,265 @@
angular.module('app').config(['$translateProvider', 'localeFormatProvider', function($translateProvider, localeFormatProvider) {
// Declare number format settings
localeFormatProvider.addFormat('fr', {
decimal: ',',
thousands: '.',
grouping: [3],
currency: ['', ' €'],
dateTime: '%A, le %e %B %Y, %X',
date: '%d/%m/%Y',
time: '%H:%M:%S',
periods: ['AM', 'PM'], // unused
days: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
shortDays: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
months: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],
shortMonths: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.']
});
$translateProvider.translations('fr', {
PHRASE_EXPORT_DESC: 'Ein detaillierter JSON-Export Ihrer Konfiguration für die Verwendung in anderen Websites und Tools',
A_RATED: 'A-Klasse',
ABOUT: 'Über',
ACTION: 'Aktion',
ADDED: 'Hinzugefügt',
ADDER: 'Adder',
ADVANCED: 'Fortgeschritten',
'Advanced Discovery Scanner': 'Fortgeschrittener Aufklärungsscanner',
'Advanced Plasma Laser': 'Fortgeschrittener Plasma-Laser',
AGILITY: 'Beweglichkeit',
ALPHA: 'Alpha',
AMMO: 'Munition',
ANACONDA: 'Anaconda',
PHRASE_CONFIRMATION: 'Sind Sie sicher?',
ARMOUR: 'Panzerung',
ASP_EXPLORER: 'Asp Explorer',
am: 'Automatische Feldwartungseinheit',
AVAILABLE: 'Verfügbar',
BACKUP: 'Sicherungsdatei',
'Basic Discovery Scanner': 'Einfacher Aufklärungsscanner',
bl: 'Strahlenlaser',
BELUGA_LINER: 'Beluga Liner',
BETA: 'beta',
BINS: 'Behälter',
BOOST: 'Boost',
BUILD: 'Konfiguration',
BUILD_NAME: 'Konfigurationsname',
BUILDS: 'Konfigurationen',
BULKHEADS: 'Rumpfhüllenverstärkung',
ul: 'Salvenlaser',
BUY: 'Kaufen',
CANCEL: 'Abbrechen',
c: 'Kanone',
CAPITAL: 'kapital',
CARGO: 'Fracht',
CARGO_HATCH: 'Frachtluke',
cr: 'Frachtgestell',
cs: 'Frachtscanner',
CELLS: 'Zellen',
CHAFF_LAUNCHER: 'Düppel-Werfer',
CLOSE: 'Schließen',
COBRA_MK_III: 'Cobra MK III',
COBRA_MK_IV: 'Cobra MK IV',
cc: 'Krallensteuerung: Sammler',
COMPARE: 'Vergleichen',
COMPARE_ALL: 'Alles Vergleichen',
COMPARISON: 'Vergleich',
COMPARISONS: 'Vergleiche',
COMPONENT: 'Komponente',
COST: 'Kostet',
COSTS: 'Kosten',
cm: 'Gegenmaßnahme',
CR: 'CR',
CREATE: 'Erstellen',
CREATE_NEW: 'Neu Erstellen',
CREDITS: 'Credits',
Cytoscrambler: 'Zytostreuer',
DAMAGE: 'Schaden',
DELETE: 'Löschen',
DELETE_ALL: 'Alles Löschen',
DEP: 'Ausg',
DEPLOYED: 'Ausgefahren',
DETAILED_EXPORT: 'Detailiertes Exportieren',
'Detailed Surface Scanner': 'Detailoberflächenscanner',
DIAMONDBACK_EXPLORER: 'Diamondback-Erkunder',
DIAMONDBACK_SCOUT: 'Diamondback-Aufklärer',
DISABLED: 'Deaktiviert',
DISCOUNT: 'Rabatt',
Distruptor: 'Disruptor',
dc: 'Standard-Landecomputer',
DOLPHIN: 'Dolphin',
DONE: 'Fertig',
DPS: 'DPS',
EAGLE: 'Eagle',
EDIT_DATA: 'Bearbeiten',
EFFICIENCY: 'Effizienz',
'Electronic Countermeasure': 'Elektronische Gegenmaßnahme',
EMPTY: 'leer',
ENFORCER: 'Vollstrecker',
ENG: 'FAH',
PHRASE_ENTER_BUILD_NAME: '',
EPS: 'en/s',
EXPORT: 'Exportieren',
FEDERAL_CORVETTE: 'Föderale Korvette',
FEDERAL_DROPSHIP: 'Föderales Abwurfschiff',
FEDERAL_DROPSHIP_MK_II: 'Föderales Abwurfschiff Mk II',
FEDERAL_GUNSHIP: 'Föderales Kanonenschiff',
FER_DE_LANCE: 'Fer-de-Lance',
FIXED: '',
FORUM: 'Forum',
fc: 'Splitterkanone',
fd: 'Frameshift-Antrieb',
ws: 'Sogwolkenscanner',
FSD: 'FSA',
fi: 'FSA-Unterbrecher',
FUEL: 'Treibstoff',
fs: 'Treibstoffsammler',
ft: 'Treibstofftank',
fx: 'Krallensteuerung Treibstoffstransfer',
FULL_TANK: 'Tank voll',
GIMBALLED: 'Kardianisch',
H: 'H',
HARDPOINTS: 'Waffenaufhängungen',
hb: 'Krallen-Steuereinheit (Ladelukenöffner)',
HAULER: 'Hauler',
'Heat Sink Launcher': 'Kühlkörperwerfer',
HUGE: 'Riesig',
HULL: 'Hülle',
hr: 'Rumpfhüllenverstärkung (Paket)',
IMPERIAL_CLIPPER: 'Imperialer Clipper',
IMPERIAL_COURIER: 'Imperialer Kurier',
IMPERIAL_CUTTER: 'Imperialer Cutter',
IMPERIAL_EAGLE: 'Imperialer Eagle',
IMPERIAL_HAMMER: 'Imperialer Hammer',
IMPORT: 'Importieren',
IMPORT_ALL: 'Alles Importieren',
INSURANCE: 'Versicherung',
'Intermediate Discover Scanner': 'Mittlerer Aufklärungsscanner',
INTERNAL_COMPARTMENTS: 'Innenbereichkabine',
JUMP_RANGE: 'Sprungreichweite',
JUMPS: 'Sprünge',
kw: 'Tötungsbefehlscanner',
KRAIT: 'Krait',
L: 'L',
LADEN: 'Beladen',
LANGUAGE: 'Sprache',
LARGE: 'Groß',
ls: 'Lebenserhaltung',
'Lightweight Alloy': 'Leichte Legierung',
LOCK_FACTOR: 'Massensperrefaktor',
LS: 'LS',
LY: 'LJ',
M: 'M',
'm/s': 'M/Sec.',
MASS: 'Masse',
MAX: 'max',
MAX_MASS: 'maximale Masse',
MEDIUM: 'Mittel',
'Military Grade Composite': 'Militär-Komposit',
nl: 'Minenwerfer',
'Mining Lance': 'Lanzenabbaulaser',
ml: 'Abbaulaser',
'Mirrored Surface Composite': 'Gespiegelte-Oberfläche-Komposit',
mr: 'Raketenbatterie',
mc: 'Mehrfachgeschütz',
NET_COST: 'Nettokosten',
NO: 'Nein',
NO_RETROFITTING_CHANGES: 'Keine Umrüständerungen',
NONE: 'Nichts',
NONE_CREATED: 'Nichts erstellt',
OFF: 'Aus',
ON: 'An',
OPTIMAL: 'optimal',
OPTIMAL_MASS: 'optimale Masse',
OPTIMIZE_MASS: 'Masse optimieren',
ORCA: 'Orca',
OVERWRITE: 'Überschreiben',
Pacifier: 'Friedensstifter',
'Pack-Hound': 'Schwarmwerfer',
PANTHER_CLIPPER: 'Panter Clipper',
PHRASE_IMPORT: 'JSON hier einfügen oder hier importieren',
PEN: 'Durchdr',
PENETRATION: 'Durchdringung',
PERMALINK: 'Permalink',
pa: 'Plasmabeschleuniger',
POINT_DEFENCE: 'Punktverteidigung',
POWER: 'Energie',
pd: 'Energieverteiler',
pp: 'Kraftwerk',
PRI: 'Prio',
PRIORITY: 'Priorität',
psg: 'Prismaschildgenerator',
PROCEED: 'Fortfahren',
pc: 'Krallensteuerung: Erzsucher',
pl: 'Impulslaser',
PWR: 'En',
PYTHON: 'Python',
rg: 'Schienenkanone',
RANGE: 'Reichweite',
RATE: 'Rate',
'Reactive Surface Composite': 'Reaktive-Oberfläche-Komposit',
RECHARGE: 'Aufladen',
rf: 'Raffinerie',
REFUEL_TIME: 'Auftankzeit',
'Reinforced Alloy': 'Verstärkte Legierungen',
RELOAD: 'Aktualisieren',
RENAME: 'Umbenennen',
REPAIR: 'Reparieren',
RESET: 'Zurücksetzen',
RET: 'eing',
RETRACTED: 'Eingefahren',
RETROFIT_COSTS: 'Nachrüstkosten',
RETROFIT_FROM: 'Nachrüsten von',
ROF: 'Kad',
S: 'S',
SAVE: 'Speichern',
sc: 'Scanner',
PHRASE_SELECT_BUILDS: 'Wähle Konfigurationen zum Vergleichen',
SELL: 'Verkaufen',
s: 'Sensoren',
SETTINGS: 'Konfiguration',
sb: 'Schildverstärker',
scb: 'Schildzellenbank',
sg: 'Schildgenerator',
SHIELDS: 'Schilde',
SHIP: 'Schiff',
SHIPS: 'Schiffe',
SHORTENED: 'Gekürzt',
SIDEWINDER: 'Sidewinder',
SIZE: 'Größe',
SKIP: 'Überspringen',
SMALL: 'S',
SPEED: 'Geschwindigkeit',
STANDARD: 'Standard',
STANDARD_DOCKING_COMPUTER: 'Landecomputer',
STOCK: 'Standard',
SYS: 'SYS',
T: 'T',
T_LOAD: 'T-Lad',
THE_HUNTER: 'The Hunter',
'The Retributor': 'Retributor',
t: 'Schubdüsen',
TIME: 'Dauer',
tp: 'Torpedoaufhängung',
TOTAL: 'Gesamt',
TOTAL_RANGE: 'Maximale Reichweite',
TURRET: 'Geschützturm',
TYPE: 'Typ',
TYPE_6_TRANSPORTER: 'Typ-6 Transporter',
TYPE_7_TRANSPORTER: 'Typ-7 Transporter',
TYPE_9_HEAVY: 'Typ-9 Transporter (schwer)',
U: 'U',
UNLADEN: 'Unbeladen',
UPDATE_NOTIFICATION: 'Update verfügbar! Klicken zum Aktualisieren',
URL: 'URL',
UTILITY: 'Werkzeug',
UTILITY_MOUNTS: 'Werkzeug-Steckplatz',
VERSION: 'Version',
VIPER: 'Viper',
VULTURE: 'Vulture',
WEP: 'WAF',
YES: 'Ja'
})
.registerAvailableLanguageKeys(['fr'], { 'fr_FR': 'fr', 'fr_CA': 'fr' });
}]);

257
app/js/i18n/ru.js Normal file
View File

@@ -0,0 +1,257 @@
angular.module('app').config(['$translateProvider', 'localeFormatProvider', function($translateProvider, localeFormatProvider) {
// Declare number format settings
localeFormatProvider.addFormat('ru', {
decimal: ',',
thousands: '\xa0',
grouping: [3],
currency: ['', ' руб.'],
dateTime: '%A, %e %B %Y г. %X',
date: '%d.%m.%Y',
time: '%H:%M:%S',
periods: ['AM', 'PM'],
days: ['воскресенье', 'понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота'],
shortDays: ['вс', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'],
months: ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'],
shortMonths: ['янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек']
});
$translateProvider.translations('ru', {
PHRASE_EXPORT_DESC: '',
A_RATED: 'А-Класса',
ABOUT: 'О сайте',
ACTION: 'Действие',
ADDED: 'Добавлено',
ADVANCED: 'Продвинутый',
'Advanced Discovery Scanner': 'Продвинутый исследовательский сканер',
'Advanced Plasma Laser': 'Продвинутый плазменный лазер',
AGILITY: 'Маневренность',
ALPHA: 'Альфа',
AMMO: 'Боекомплект',
ANACONDA: 'Анаконда',
PHRASE_CONFIRMATION: 'Вы уверены?',
ARMOUR: 'Броня',
ASP_EXPLORER: 'Асп Эксплорер',
am: 'Устройство авторемонта',
AVAILABLE: 'доступно',
BACKUP: 'Поддержка / запас / бэкап',
'Basic Discovery Scanner': 'Базовый исследовательский сканер',
bl: 'Лучевой лазер',
BELUGA_LINER: 'Лайнер Белуга',
BETA: 'Бета',
BINS: '',
BOOST: 'форсаж',
BUILD: 'cборка',
BUILD_NAME: 'название сборки',
BUILDS: 'cборки',
BULKHEADS: 'Переборки',
ul: 'пульс-лазер',
BUY: 'купить',
CANCEL: 'отменить',
c: 'Пушка',
CAPITAL: 'Крупный',
CARGO: 'Груз',
CARGO_HATCH: 'Грузовой трюм',
cr: 'Грузовой модуль',
cs: 'Сканер груза',
CELLS: 'Ячейки',
'Chaff Launcher': 'Постановщик помех',
CLOSE: 'закрыть',
COBRA_MK_III: 'Кобра МК-III',
COBRA_MK_IV: 'Кобра МК-IV',
cc: 'Контроллер "дрон-сборщик"',
COMPARE: 'сравнить ',
COMPARE_ALL: 'сравнить все',
COMPARISON: 'сравнение',
COMPARISONS: 'сравнения',
COMPONENT: 'Компонент',
COST: 'Стоимость/Цена',
COSTS: 'Расходы',
cm: 'Контрмеры',
CR: 'кр.',
CREATE: 'создать',
CREATE_NEW: 'Создать снова',
CREDITS: 'Кредиты',
Cytoscrambler: 'Weapon PP - In game name',
DAMAGE: 'Урон',
DELETE: 'Удалить',
DELETE_ALL: 'Удалить все',
DEP: 'Вып.',
DEPLOYED: 'Готово',
DETAILED_EXPORT: 'Подробный экспорт',
'Detailed Surface Scanner': 'Подробный сканер поверхности',
DIAMONDBACK_EXPLORER: 'Даймондбэк Эксплорер',
DIAMONDBACK_SCOUT: 'Даймондбэк Скаут',
DISABLED: 'Отключено',
DISCOUNT: 'Скидка',
Distruptor: 'Дисраптор',
dc: 'Стыковочный компьютер',
DOLPHIN: 'Дельфин',
DONE: 'готово',
DPS: 'Урон в секунду',
EAGLE: 'Орел',
EDIT_DATA: 'Редактирование',
EFFICIENCY: 'Эффективность',
'Electronic Countermeasure': 'Электронное противодействие',
EMPTY: 'пусто',
ENFORCER: 'Weapon PP - In game name',
ENG: 'ДВГ',
PHRASE_ENTER_NAME: '',
EPS: 'э/с',
EXPORT: 'Экспорт',
FEDERAL_CORVETTE: 'Федеральный Корвет',
FEDERAL_DROPSHIP: 'Федеральный Десантный Корабль',
FEDERAL_DROPSHIP_MK_II: 'Федеральный Десантный Корабль мод.II',
FEDERAL_GUNSHIP: 'Федеральный Боевой Корабль',
FER_DE_LANCE: 'Фер-де-Ланс',
FIXED: 'Фиксированое',
FORUM: 'Форум',
fc: 'Осколочное Орудие',
fd: 'ФСД',
ws: 'Сканер следа',
FSD: 'ФСД',
fi: 'ФСД Перехватчик',
FUEL: 'Топливо',
fs: 'Топливозаборник',
ft: 'Топливный бак',
fx: 'Устройство передачи топлива',
FULL_TANK: 'Полный бак',
GIMBALLED: 'Доводимое',
HARDPOINTS: 'точки установки вооружения',
hb: 'Контроллер "дрон-взломщик"',
HAULER: 'Хаулер',
'Heat Sink Launcher': 'Охладитель',
HULL: 'Корпус',
hr: 'Набор усиления корпуса',
IMPERIAL_CLIPPER: 'Имперский Клипер',
IMPERIAL_COURIER: 'Имперский Курьер',
IMPERIAL_CUTTER: 'Имперский Куттер',
IMPERIAL_EAGLE: 'Имперский Орёл',
IMPERIAL_HAMMER: 'Имперский Молот',
IMPORT: 'импортировать ',
IMPORT_ALL: 'импортировать все',
INSURANCE: 'Страховка',
'Intermediate Discover Scanner': 'Средний Исследовательский Сканер',
INTERNAL_COMPARTMENTS: 'внутренние отсеки',
JUMP_RANGE: 'Дальность прыжка',
JUMPS: 'Прыжки',
kw: 'Сканер преступников',
KRAIT: 'Крэйт',
LADEN: 'Груженый',
LANGUAGE: 'Язык',
ls: 'Система жизнеобеспечения',
'Lightweight Alloy': 'Легкий сплав',
LOCK_FACTOR: 'Блокирующий Фактор (Фактор массы)',
LS: 'Св.сек',
LY: 'Св.лет',
'm/s': 'м/с',
MASS: 'Масса',
MAX: 'Макс',
MAX_MASS: 'Максимальная масса',
MEDIUM: 'Средний',
'Military Grade Composite': 'Композит боевого класса',
nl: 'Миномет',
'Mining Lance': 'Бурильная сулица',
ml: 'Шахтерский лазер',
'Mirrored Surface Composite': 'Композит с зеркальной поверхностью',
mr: 'Ракетная установка',
mc: 'Многоствольная пушка',
NET_COST: 'разница в цене',
NO: 'Нет',
PHRASE_NO_BUILDS: '',
NO_RETROFITTING_CHANGES: 'нет ранних версий сборки\конфигурации',
NONE: 'ни один',
NONE_CREATED: 'не создано',
OFF: 'выкл.',
ON: 'вкл.',
OPTIMAL: 'Оптимальный',
OPTIMAL_MASS: 'Оптимальная масса',
OPTIMIZE_MASS: 'Оптимизировать массу',
ORCA: 'Орка',
OVERWRITE: 'перезаписать',
Pacifier: 'Миротворец',
'Pack-Hound': 'Ракеты "Собачья стая" or original name(eng)',
PANTHER_CLIPPER: 'Клипер Пантера',
PHRASE_IMPORT: 'Для импорта вставьте код в эту форму',
PEN: 'Класс бронепробития. short - "прбт."',
PENETRATION: 'Пробитие',
PERMALINK: 'Постоянная ссылка',
pa: 'Ускоритель плазмы',
'Point Defence': 'Противоракетная защита',
POWER: 'Мощность/сила/энергия',
pd: 'Распределитель энергии',
pp: 'Силовая установка / реактор',
PRI: 'Осн',
PRIORITY: 'Приоритет',
psg: 'Генератор призматического щита',
PROCEED: 'продолжить',
pc: 'Контроллер "Дрон-исследователь"',
pl: 'Импульсный лазер',
PWR: 'Е',
PYTHON: 'Питон',
rg: 'Рельсовая пушка',
RANGE: 'Дальность',
RATE: 'скорость',
'Reactive Surface Composite': 'Композитно-реактивная поверхность',
RECHARGE: 'Перезарядка',
rf: 'Переработка',
REFUEL_TIME: 'Время дозаправки',
'Reinforced Alloy': 'Усиленный сплав',
RELOAD: 'Перезарядить',
RENAME: 'Переименовать',
REPAIR: 'Починка',
RESET: 'Сброс',
RET: 'сокр',
RETRACTED: 'Убрано',
RETROFIT_COSTS: 'цена модификации',
RETROFIT_FROM: 'модификация от',
ROF: 'скорость стрельбы',
SAVE: 'Сохранить',
sc: 'Сканер',
PHRASE_SELECT_BUILDS: 'Выберите конфигурацию для сравнения',
SELL: 'Продать',
s: 'Сенсоры',
SETTINGS: 'Настройки',
sb: 'Усилитель щита',
scb: 'Батареи перезарядки щита',
sg: 'Генератор щита',
SHIELDS: 'Щиты',
SHIP: 'Корабль',
SHIPS: 'Корабли',
SHORTENED: 'Укороченный',
SIDEWINDER: 'Сайдвиндер',
SIZE: 'размер',
SKIP: 'пропустить',
SMALL: 'Малый',
SPEED: 'скорость',
STANDARD: 'Стандартный',
'Standard Docking Computer': 'Стандартный стыковочный компьютер',
STOCK: 'Стандартная комплектация',
SYS: 'Сис',
T: 'Т',
T_LOAD: 'Тепловая нагрузка',
THE_HUNTER: 'Охотник',
'The Retributor': 'Орудие Возмездия',
t: 'Ускорители',
TIME: 'Время',
tp: 'Торпедная установка',
TOTAL: 'Всего',
TOTAL_RANGE: 'Полный радиус',
TURRET: 'Туррель',
TYPE: 'Тип',
TYPE_6_TRANSPORTER: 'Перевозчик Тип-6',
TYPE_7_TRANSPORTER: 'Перевозчик Тип-7',
TYPE_9_HEAVY: 'Перевозчик Тип-9 Тяжелый',
UNLADEN: 'Пустой',
UPDATE_NOTIFICATION: 'Доступно обновление. Нажмите для обновления.',
URL: 'Ссылка',
UTILITY: '',
UTILITY_MOUNTS: 'Вспомогательное оборудование',
VERSION: 'Версия',
VIPER: 'Вайпер',
VULTURE: 'Вультура',
YES: 'Да'
})
.registerAvailableLanguageKeys(['ru'], { 'ru_RU': 'ru' });
}]);

View File

@@ -0,0 +1,36 @@
angular.module('app').provider('localeFormat', function localeFormatProvider() {
var formats = {
en: {
decimal: '.',
thousands: ',',
grouping: [3],
currency: ['$', ''],
dateTime: '%a %b %e %X %Y',
date: '%m/%d/%Y',
time: '%H:%M:%S',
periods: ['AM', 'PM'],
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
}
};
function LocaleFormat(formatMap) {
this.formatMap = formatMap;
this.get = function(lang) {
return this.formatMap[lang] ? this.formatMap[lang] : this.formatMap.en;
};
}
this.addFormat = function(langCode, formatDetails) {
formats[langCode] = formatDetails;
};
this.$get = [function() {
return new LocaleFormat(formats);
}];
});

View File

@@ -4,6 +4,7 @@
angular.module('app').service('Persist', ['$window', 'lodash', function($window, _) {
var LS_KEY_BUILDS = 'builds';
var LS_KEY_COMPARISONS = 'comparisons';
var LS_KEY_LANG = 'NG_TRANSLATE_LANG_KEY';
var LS_KEY_COST_TAB = 'costTab';
var LS_KEY_INSURANCE = 'insurance';
var LS_KEY_DISCOUNTS = 'discounts';
@@ -31,6 +32,22 @@ angular.module('app').service('Persist', ['$window', 'lodash', function($window,
hasBuilds: buildCount > 0,
hasComparisons: Object.keys(this.comparisons).length > 0
};
this.put = function(name, value) {
if (!this.lsEnabled) {
return;
}
localStorage.setItem(name, value);
};
this.get = function(name) {
return this.lsEnabled ? localStorage.getItem(name) : null;
};
this.getLangCode = function() {
return this.lsEnabled ? localStorage.getItem(LS_KEY_LANG) : 'en';
};
/**
* Persist a ship build in local storage.
*

View File

@@ -17,16 +17,7 @@ angular.module('shipyard', ['ngLodash'])
1.945, // Mirrored
1.945 // Reactive
])
.value('commonArray', [
'Power Plant',
'Thrusters',
'Frame Shift Drive',
'Life Support',
'Power Distributor',
'Sensors',
'Fuel Tank'
])
// Map to lookup group labels/names for component grp
// Map to lookup group labels/names for component grp, used for JSON Serialization
.value('GroupMap', {
// Common
pp: 'Power Plant',
@@ -81,20 +72,6 @@ angular.module('shipyard', ['ngLodash'])
'Gimballed': 'G',
'Turret': 'T'
})
.value('shipSize', [
'N/A',
'Small',
'Medium',
'Large',
'Capital'
])
.value('hardPointClass', [
'Utility',
'Small',
'Medium',
'Large',
'Huge'
])
/**
* Array of all Ship properties (facets) organized into groups
* used for ship comparisons.
@@ -103,91 +80,89 @@ angular.module('shipyard', ['ngLodash'])
*/
.value('ShipFacets', [
{ // 0
title: 'Agility',
title: 'agility',
props: ['agility'],
unit: '',
fmt: 'fCrd'
},
{ // 1
title: 'Speed',
title: 'speed',
props: ['speed', 'boost'],
lbls: ['Thrusters', 'Boost'],
lbls: ['thrusters', 'boost'],
unit: 'm/s',
fmt: 'fRound'
},
{ // 2
title: 'Armour',
title: 'armour',
props: ['armour'],
unit: '',
fmt: 'fCrd'
},
{ // 3
title: 'Shields',
title: 'shields',
props: ['shieldStrength'],
unit: 'MJ',
fmt: 'fRound'
},
{ // 4
title: 'Jump Range',
title: 'jump range',
props: ['unladenRange', 'fullTankRange', 'ladenRange'],
lbls: ['Max', 'Full Tank', 'Laden'],
lbls: ['max', 'full tank', 'laden'],
unit: 'LY',
fmt: 'fRound'
},
{ // 5
title: 'Mass',
title: 'mass',
props: ['unladenMass', 'ladenMass'],
lbls: ['Unladen', 'Laden'],
lbls: ['unladen', 'laden'],
unit: 'T',
fmt: 'fRound'
},
{ // 6
title: 'Cargo',
title: 'cargo',
props: ['cargoCapacity'],
unit: 'T',
fmt: 'fRound'
},
{ // 7
title: 'Fuel',
title: 'fuel',
props: ['fuelCapacity'],
unit: 'T',
fmt: 'fRound'
},
{ // 8
title: 'Power',
title: 'power',
props: ['powerRetracted', 'powerDeployed', 'powerAvailable'],
lbls: ['Retracted', 'Deployed', 'Available'],
lbls: ['retracted', 'deployed', 'available'],
unit: 'MW',
fmt: 'fPwr'
},
{ // 9
title: 'Cost',
title: 'cost',
props: ['totalCost'],
unit: 'CR',
fmt: 'fCrd'
},
{ // 10
title: 'Total Range',
title: 'total range',
props: ['unladenTotalRange', 'ladenTotalRange'],
lbls: ['Unladen', 'Laden'],
lbls: ['unladen', 'laden'],
unit: 'LY',
fmt: 'fRound'
},
{ // 11
title: 'DPS',
props: ['totalDps'],
lbls: ['Dps'],
lbls: ['DPS'],
unit: '',
fmt: 'fRound'
}
])
/**
* Set of all available / theoretical discounts
*
* @type {Object}
*/
.value('Discounts', {
'None': 1,
'0%': 1,
'5%': 0.95,
'10%': 0.90,
'15%': 0.85,

View File

@@ -1,4 +1,10 @@
angular.module('shipyard').service('Components', ['lodash', 'ComponentsDB', 'ShipsDB', 'ComponentSet', function(_, C, Ships, ComponentSet) {
angular.module('shipyard').service('Components', ['lodash', 'ComponentsDB', 'ShipsDB', 'ComponentSet', 'GroupMap', function(_, C, Ships, ComponentSet, GroupMap) {
var GrpNameToCodeMap = {};
for (var grp in GroupMap) {
GrpNameToCodeMap[GroupMap[grp]] = grp;
}
this.cargoScoop = function() {
return { name: 'Cargo Hatch', class: 1, rating: 'H', power: 0.6 };
@@ -36,10 +42,11 @@ angular.module('shipyard').service('Components', ['lodash', 'ComponentsDB', 'Shi
var groups = {};
if (groupName) {
if (!C.internal[groupName]) {
var grpCode = GrpNameToCodeMap[groupName];
if (grpCode && !C.internal[grpCode]) {
throw 'Invalid internal group: ' + groupName;
}
groups[groupName] = C.internal[groupName];
groups[grpCode] = C.internal[grpCode];
} else if (name) {
groups = C.internal;
} else {
@@ -62,10 +69,11 @@ angular.module('shipyard').service('Components', ['lodash', 'ComponentsDB', 'Shi
var groups = {};
if (groupName) {
if (!C.hardpoints[groupName]) {
var grpCode = GrpNameToCodeMap[groupName];
if (grpCode && !C.hardpoints[grpCode]) {
throw 'Invalid internal group: ' + groupName;
}
groups[groupName] = C.hardpoints[groupName];
groups[grpCode] = C.hardpoints[grpCode];
} else if (name) {
groups = C.hardpoints;
} else {

View File

@@ -84,6 +84,14 @@ div, a, li {
text-align: center;
}
.cap {
text-transform: capitalize;
}
.upp {
text-transform: uppercase;
}
.scroll-x {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
@@ -114,6 +122,7 @@ h3 {
u { // Unit (Mj, Km, etc)
font-size: 0.8em;
text-decoration: none;
text-transform: none;
}
a, a:visited {

View File

@@ -5,6 +5,7 @@ button {
fill: @primary;
}
border: none;
text-transform: capitalize;
font-family: @fStandard;
vertical-align: middle;
padding: 0.5em;

View File

@@ -50,6 +50,7 @@ header {
padding : 0 1em;
cursor: pointer;
color: @warning;
text-transform: capitalize;
// Less than 600px screen width: hide text
&.disabled {

View File

@@ -113,6 +113,10 @@ select {
}
}
.lc {
text-overflow: ellipsis;
}
.c {
display: inline-block;
width: 2em;

View File

@@ -36,6 +36,7 @@
}
.l {
text-transform: capitalize;
margin-right: 0.8em;
}
@@ -55,6 +56,7 @@
}
.empty {
text-transform: uppercase;
font-size: 1.3em;
color: lighten(@primary-bg, 12%);
text-align: center;

View File

@@ -1,5 +1,5 @@
<div id="app-update" ng-show="appCacheUpdate">
<a href="#" onclick="window.location.reload()">Update Available! Click to Refresh</a>
<a href="#" onclick="window.location.reload()">{{ 'PHRASE_UPDATE_RDY' | translate }}</a>
</div>
<header>
@@ -7,7 +7,7 @@
<div class="l menu">
<div class="menu-header" ng-class="{selected: openedMenu=='s'}" ng-click="openMenu($event,'s')">
<svg class="icon warning"><use xlink:href="#rocket"></use></svg><span class="menu-item-label"> Ships</span>
<svg class="icon warning"><use xlink:href="#rocket"></use></svg><span class="menu-item-label"> {{'ships' | translate}}</span>
</div>
<div class="menu-list dbl no-wrap" ng-if="openedMenu=='s'">
<a class="block" ng-repeat="(shipId,ship) in ships" ui-sref-active="active" ui-sref="outfit({shipId:shipId, code:null, bn:null})">{{::ship.properties.name}}</a>
@@ -16,7 +16,7 @@
<div class="l menu">
<div class="menu-header" ng-class="{selected: openedMenu=='b', disabled: !bs.hasBuilds}" ng-click="openMenu($event,'b')">
<svg class="icon warning" ng-class="{'warning-disabled': !bs.hasBuilds}"><use xlink:href="#hammer"></use></svg><span class="menu-item-label"> Builds</span>
<svg class="icon warning" ng-class="{'warning-disabled': !bs.hasBuilds}"><use xlink:href="#hammer"></use></svg><span class="menu-item-label"> {{'builds' | translate}}</span>
</div>
<div class="menu-list" ng-if="openedMenu=='b'" ng-click="$event.stopPropagation();">
<div class="dbl" >
@@ -32,44 +32,48 @@
<div class="l menu">
<div class="menu-header" ng-class="{selected: openedMenu=='comp', disabled: !bs.hasBuilds}" ng-click="openMenu($event,'comp')">
<svg class="icon warning" ng-class="{'warning-disabled': !bs.hasBuilds}"><use xlink:href="#stats-bars"></use></svg><span class="menu-item-label"> Compare</span>
<svg class="icon warning" ng-class="{'warning-disabled': !bs.hasBuilds}"><use xlink:href="#stats-bars"></use></svg><span class="menu-item-label"> {{'compare' | translate}}</span>
</div>
<div class="menu-list" ng-if="openedMenu=='comp'" ng-click="$event.stopPropagation();" style="white-space: nowrap;">
<span ng-if="!bs.hasComparisons">None Created</span>
<span class="cap" ng-if="!bs.hasComparisons" translate="none created"></span>
<a ng-repeat="(name, comp) in allComparisons" ui-sref-active="active" class="block name" ui-sref="compare({name:name})" ng-bind="name"></a>
<hr />
<a ui-sref="compare({name: 'all'})" class="block">Compare All</a>
<a ui-sref="compare({name: null})" class="block">Create New</a>
<a ui-sref="compare({name: 'all'})" class="block cap" translate="compare all"></a>
<a ui-sref="compare({name: null})" class="block cap" translate="create new"></a>
</div>
</div>
<div class="r menu">
<div class="menu-header" ng-class="{selected: openedMenu=='settings'}" ng-click="openMenu($event,'settings')">
<svg class="icon xl warning"><use xlink:href="#cogs"></use></svg><span class="menu-item-label"> Settings</span>
<svg class="icon xl warning"><use xlink:href="#cogs"></use></svg><span class="menu-item-label"> {{'settings' | translate}}</span>
</div>
<div class="menu-list no-wrap" ng-if="openedMenu=='settings'" ng-click="$event.stopPropagation();">
<div class="menu-list no-wrap cap" ng-if="openedMenu=='settings'" ng-click="$event.stopPropagation();">
<ul>
Insurance
<li><select ng-model="insurance.current" ng-options="ins.name for (i,ins) in insurance.opts" ng-change="updateInsurance()"></select></li>
{{'language' | translate}}
<li><select class="cap" ng-model="language.current" ng-options="langCode as langName for (langCode,langName) in language.opts" ng-change="changeLanguage()"></select></li>
</ul><br>
<ul>
Ship Discount
<li><select ng-model="discounts.ship" ng-options="i for (i,d) in discounts.opts" ng-change="updateDiscount()"></select></li>
{{'insurance' | translate}}
<li><select class="cap" ng-model="insurance.current" ng-options="ins.name | translate for (i,ins) in insurance.opts" ng-change="updateInsurance()"></select></li>
</ul><br>
<ul>
Component Discount
<li><select ng-model="discounts.components" ng-options="i for (i,d) in discounts.opts" ng-change="updateDiscount()"></select></li>
{{'ship' | translate}} {{'discount' | translate}}
<li><select class="cap" ng-model="discounts.ship" ng-options="i for (i,d) in discounts.opts" ng-change="updateDiscount()"></select></li>
</ul><br>
<ul>
{{'component' | translate}} {{'discount' | translate}}
<li><select class="cap" ng-model="discounts.components" ng-options="i for (i,d) in discounts.opts" ng-change="updateDiscount()"></select></li>
</ul>
<hr />
<ul>
Builds & Comparisons
<li><a href="#" class="block" ng-click="backup($event)">Backup</a></li>
<li><a href="#" class="block" ng-click="detailedExport($event)">Detailed Export</a></li>
<li><a href="#" class="block" ui-sref="modal.import">Import</a></li>
<li><a href="#" class="block" ui-sref="modal.delete">Delete All</a></li>
{{'builds' | translate}} & {{'comparisons' | translate}}
<li><a href="#" class="block" ng-click="backup($event)" translate="backup"></a></li>
<li><a href="#" class="block" ng-click="detailedExport($event)" translate="detailed export"></a></li>
<li><a href="#" class="block" ui-sref="modal.import" translate="import"></a></li>
<li><a href="#" class="block" ui-sref="modal.delete" translate="delete all"></a></li>
</ul>
<hr />
<a href="#" ui-sref="modal.about" class="block">About</a>
<a href="#" ui-sref="modal.about" class="block" translate="about"></a>
</div>
</div>

View File

@@ -1,17 +1,17 @@
<div class="sz">{{::['U','S','M','L','H'][hp.maxClass]}}</div>
<div class="empty" ng-if="!hp.c">EMPTY</div>
<div class="sz">{{['U','S','M','L','H'][hp.maxClass] | translate}}</div>
<div class="empty" ng-if="!hp.c" translate="empty"></div>
<div ng-if="hp.c">
{{hp.c.class}}{{hp.c.rating}}<span ng-if="hp.c.mode">/{{hp.c.mode}}{{hp.c.missile}}</span> {{hp.c.name || lbl}}
{{hp.c.class}}{{hp.c.rating}}<span ng-if="hp.c.mode">/{{hp.c.mode}}{{hp.c.missile}}</span> {{hp.c.name || hp.c.grp | translate}}
<div class="r">{{hp.c.mass}} <u>T</u></div>
<div class="cb">
<div class="l" ng-if="hp.c.damage">Damage: {{hp.c.damage}} <span ng-if="hp.c.ssdam">({{$r.fCrd(hp.c.ssdam)}} <u>Mj</u>)</span></div>
<div class="l" ng-if="hp.c.dps">DPS: {{hp.c.dps}} <span ng-if="hp.c.mjdps">({{$r.fCrd(hp.c.mjdps)}} <u>Mj</u>)</span></div>
<div class="l" ng-if="hp.c.thermload">T-Load: {{hp.c.thermload}}</div>
<div class="l" ng-if="hp.c.type">Type: {{hp.c.type}}</div>
<div class="l" ng-if="hp.c.rof">ROF: {{hp.c.rof}}<u>/s</u></div>
<div class="l" ng-if="hp.c.armourpen">Pen: {{hp.c.armourpen}}</div>
<div class="l" ng-if="hp.c.damage">{{'damage' | translate}}: {{hp.c.damage}} <span ng-if="hp.c.ssdam">({{$r.fCrd(hp.c.ssdam)}} <u>MJ</u>)</span></div>
<div class="l" ng-if="hp.c.dps">{{'DPS' | translate}}: {{hp.c.dps}} <span ng-if="hp.c.mjdps">({{$r.fCrd(hp.c.mjdps)}} <u>MJ</u>)</span></div>
<div class="l" ng-if="hp.c.thermload">{{'T_LOAD' | translate}}: {{hp.c.thermload}}</div>
<div class="l" ng-if="hp.c.type">{{'type' | translate}}: {{hp.c.type}}</div>
<div class="l" ng-if="hp.c.rof">{{'ROF' | translate}}: {{hp.c.rof}}<u>/s</u></div>
<div class="l" ng-if="hp.c.armourpen">{{'pen' | translate}}: {{hp.c.armourpen}}</div>
<div class="l" ng-if="hp.c.shieldmul">+{{$r.fRPct(hp.c.shieldmul)}}</div>
<div class="l" ng-if="hp.c.range">{{hp.c.range}} <u>KM</u></div>
<div class="l" ng-if="hp.c.ammo">Ammo: {{$r.fCrd(hp.c.clip)}}/{{$r.fCrd(hp.c.ammo)}}</div>
<div class="l" ng-if="hp.c.range">{{hp.c.range}} <u>km</u></div>
<div class="l" ng-if="hp.c.ammo">{{'ammo' | translate}}: {{$r.fCrd(hp.c.clip)}}/{{$r.fCrd(hp.c.ammo)}}</div>
</div>
</div>

View File

@@ -1,22 +1,22 @@
<div class="sz" ng-bind="c.maxClass"></div>
<div class="empty" ng-if="!c.c">EMPTY</div>
<div class="empty" ng-if="!c.c" translate="empty"></div>
<div ng-if="c.c">
<div class="l name">{{c.c.class}}{{c.c.rating}} {{c.c.name || lbl}}</div>
<div class="r">{{c.c.mass || c.c.capacity || '0'}} <u>T</u></div>
<div class="l name">{{c.c.class}}{{c.c.rating}} {{c.c.name || c.c.grp | translate}}</div>
<div class="r">{{c.c.mass || c.c.capacity || '0'}} <u translate="T"></u></div>
<div class="cb"></div>
<div class="l" ng-if="c.c.optmass">Optimal Mass: {{c.c.optmass}} <u>T</u></div>
<div class="l" ng-if="c.c.maxmass">Max Mass: {{c.c.maxmass}} <u>T</u></div>
<div class="l" ng-if="c.c.bins">{{c.c.bins}} <u>Bins</u></div>
<div class="l" ng-if="c.c.rate">Rate: {{c.c.rate}} <u>Kg/s</u>&nbsp;&nbsp;&nbsp;Refuel Time: {{$r.fTime(fuel * 1000 / c.c.rate)}}</div>
<div class="l" ng-if="c.c.ammo">Ammo: {{c.c.ammo}}</div>
<div class="l" ng-if="c.c.cells">Cells: {{c.c.cells}}</div>
<div class="l" ng-if="c.c.recharge">Recharge: {{c.c.recharge}} <u>MJ</u>&nbsp;&nbsp;&nbsp;Total: {{c.c.cells * c.c.recharge}} <u>MJ</u></div>
<div class="l" ng-if="c.c.repair">Repair: {{c.c.repair}}</div>
<div class="l" ng-if="c.c.range">Range {{c.c.range}} <u>km</u></div>
<div class="l" ng-if="c.c.time">Time: {{$r.fTime(c.c.time)}}</div>
<div class="l" ng-if="c.c.maximum">Max: {{(c.c.maximum)}}</div>
<div class="l" ng-if="c.c.rangeLS">{{c.c.rangeLS}} <u>LS</u></div>
<div class="l" ng-if="c.c.rangeLS === null"><svg class="icon"><use xlink:href="#infinite"></use></svg> <u>LS</u></div>
<div class="l" ng-if="c.c.rangeRating">Range: {{c.c.rangeRating}}</div>
<div class="l" ng-if="c.c.armouradd">+{{c.c.armouradd}} <u>Armour</u></div>
<div class="l" ng-if="c.c.optmass">{{'optimal mass' | translate}}: {{c.c.optmass}} <u translate="T"></u></div>
<div class="l" ng-if="c.c.maxmass">{{'max mass' | translate}}: {{c.c.maxmass}} <u translate="T"></u></div>
<div class="l" ng-if="c.c.bins">{{c.c.bins}} <u translate="bins"></u></div>
<div class="l" ng-if="c.c.rate">{{'rate' | translate}}: {{c.c.rate}} <u>Kg/s</u>&nbsp;&nbsp;&nbsp;{{'refuel time' | translate}}: {{$r.fTime(fuel * 1000 / c.c.rate)}}</div>
<div class="l" ng-if="c.c.ammo">{{'ammo' | translate}}: {{c.c.ammo}}</div>
<div class="l" ng-if="c.c.cells">{{'cells' | translate}}: {{c.c.cells}}</div>
<div class="l" ng-if="c.c.recharge">{{'recharge' | translate}}: {{c.c.recharge}} <u>MJ</u>&nbsp;&nbsp;&nbsp;{{'total' | translate}}: {{c.c.cells * c.c.recharge}} <u>MJ</u></div>
<div class="l" ng-if="c.c.repair">{{'repair' | translate}}: {{c.c.repair}}</div>
<div class="l" ng-if="c.c.range">{{'range' | translate}} {{c.c.range}} <u>km</u></div>
<div class="l" ng-if="c.c.time">{{'time' | translate}}: {{$r.fTime(c.c.time)}}</div>
<div class="l" ng-if="c.c.maximum">{{'max' | translate}}: {{(c.c.maximum)}}</div>
<div class="l" ng-if="c.c.rangeLS">{{c.c.rangeLS}} <u translate="LS"></u></div>
<div class="l" ng-if="c.c.rangeLS === null"><svg class="icon"><use xlink:href="#infinite"></use></svg> <u translate="LS"></u></div>
<div class="l" ng-if="c.c.rangeRating">{{'range' | translate}}: {{c.c.rangeRating}}</div>
<div class="l" ng-if="c.c.armouradd">+{{c.c.armouradd}} <u translate="armour"></u></div>
</div>

View File

@@ -26,4 +26,4 @@
<p>Help keep the lights on! Donations will be used to cover costs of running and maintaining Coriolis. Thanks for helping!</p>
<button class="r dismiss" ng-click="dismiss()">Close</button>
<button class="r dismiss cap" ng-click="dismiss()" translate="close"></button>

View File

@@ -1,4 +1,4 @@
<h2>Delete All</h2>
<p style="text-align:center;">Are you sure?</p>
<button class="l" ng-click="deleteAll()">Yes</button>
<button class="r" ng-click="dismiss()">No</button>
<h2 translate="delete all"></h2>
<p style="text-align:center;" translate="PHRASE_CONFIRMATION"></p>
<button class="l cap" ng-click="deleteAll()" translate="yes"></button>
<button class="r cap" ng-click="dismiss()" translate="no"></button>

View File

@@ -1,6 +1,6 @@
<h2 ng-bind="title"></h2>
<div ng-if="description" ng-bind="description"></div>
<h2 ng-bind="title | translate"></h2>
<div ng-if="description" ng-bind="description | translate"></div>
<div>
<textarea class="cb json" ng-click="onTextClick($event)" ng-bind="export"></textarea>
</div>
<button class="r dismiss" ng-click="dismiss()">Close</button>
<button class="r dismiss cap" ng-click="dismiss()" translate="close"></button>

View File

@@ -1,40 +1,46 @@
<h2>Import</h2>
<h2 translate="import"></h2>
<div ng-show="!processed">
<textarea class="cb json" ng-model="importString" ng-change="validateImport()" placeholder="Paste JSON or Build text Here"></textarea>
<button class="l" ng-click="process()" ng-disabled="!importValid">Proceed</button>
<textarea class="cb json" ng-model="importString" ng-change="validateImport()" placeholder="{{'PHRASE_IMPORT' | translate}}"></textarea>
<button class="l cap" ng-click="process()" ng-disabled="!importValid" translate="proceed"></button>
<div class="l warning" style="margin-left:3em;">{{errorMsg}}</div>
</div>
<div ng-show="processed">
<table class="l" style="overflow:hidden;margin: 1em 0; width: 100%;">
<thead><tr><th style="text-align:left">Ship</th><th style="text-align:left">Build Name</th><th>Action</th></tr></thead>
<thead>
<tr>
<th style="text-align:left" translate="ship"></th>
<th style="text-align:left" translate="build name"></th>
<th translate="action"></th>
</tr>
</thead>
<tbody ng-repeat="(shipId,shipBuilds) in builds">
<tr class="cb" ng-repeat="(buildName, b) in shipBuilds">
<td>{{ships[shipId].properties.name}}</td>
<td><input type="text" ng-model="b.useName"/></td>
<td style="text-align:center" ng-class="{warning: hasBuild(shipId, b.useName) == true, disabled: b.useName == ''}">
<span ng-show="b.useName">{{ hasBuild(shipId, b.useName)? 'Overwrite' : 'Create' }}</span>
<span ng-show="b.useName == ''">Skip</span>
<span ng-show="b.useName" translate="{{ hasBuild(shipId, b.useName)? 'overwrite' : 'create' }}"></span>
<span ng-show="b.useName == ''" translate="skip"></span>
</td>
</tr>
</tbody>
</table>
<table class="l" style="overflow:hidden;margin: 1em 0; width: 100%;" ng-if="comparisons">
<thead><tr><th style="text-align:left">Comparison</th><th>Action</th></tr></thead>
<thead><tr><th style="text-align:left" translate="comparison"></th><th translate="action"></th></tr></thead>
<tbody>
<tr class="cb" ng-repeat="(name, comparison) in comparisons">
<td><input type="text" ng-model="comparison.useName"/></td>
<td style="text-align:center" ng-class="{warning: hasComparison(comparison.useName) == true, disabled: comparison.useName == ''}">
<span ng-show="comparison.useName">{{ hasComparison(comparison.useName)? 'Overwrite' : 'Create' }}</span>
<span ng-show="comparison.useName == ''">Skip</span>
<span ng-show="comparison.useName" translate="{{ hasComparison(comparison.useName)? 'overwrite' : 'create' }}"></span>
<span ng-show="comparison.useName == ''" translate="skip"></span>
</td>
</tr>
</tbody>
</table>
<button class="cl l" ng-click="import()"><svg class="icon"><use xlink:href="#download"></use></svg> Import</button>
<button class="l" style="margin-left: 2em;" ng-click="processed = false" ng-show="canEdit">Edit Data</button>
<button class="cl l" ng-click="import()"><svg class="icon"><use xlink:href="#download"></use></svg> {{'import' | translate}}</button>
<button class="l cap" style="margin-left: 2em;" ng-click="processed = false" ng-show="canEdit" translate="edit data"></button>
</div>
<button class="r dismiss" ng-click="dismiss()">Cancel</button>
<button class="r dismiss cap" ng-click="dismiss()" translate="cancel"></button>

View File

@@ -1,9 +1,9 @@
<h2>Permalink</h2>
<h2 translate="permalink"></h2>
<br>
<h3>URL</h3>
<h3 translate="URL"></h3>
<input ng-model="url" size="40" ng-click="onTextClick($event)">
<br><br>
<h3>Shortened</h3>
<h3 translate="shortened"></h3>
<input ng-model="shortenedUrl" size="25" ng-click="onTextClick($event)">
<br><br>
<button class="r dismiss" ng-click="dismiss()">Close</button>
<button class="r dismiss cap" ng-click="dismiss()" translate="close"></button>

View File

@@ -1,37 +1,37 @@
<table id="comparison">
<tr ng-show="compareMode">
<td class="head">Comparison</td>
<td class="head" translate="comparison"></td>
<td>
<input ng-model="name" ng-change="nameChange()" placeholder="Enter Comparison Name" maxlength="50" />
<input ng-model="name" ng-change="nameChange()" placeholder="{{'enter name' | translate}}" maxlength="50" />
<button ng-click="save()" ng-disabled="!name || name == 'all' || saved">
<svg class="icon lg "><use xlink:href="#floppy-disk"></use></svg><span class="button-lbl"> Save</span>
<svg class="icon lg "><use xlink:href="#floppy-disk"></use></svg><span class="button-lbl"> {{'save' | translate}}</span>
</button>
<button ng-click="delete()" ng-disabled="name == 'all' || !saved"><svg class="icon lg warning "><use xlink:href="#bin"></use></svg></button>
<button ng-click="selectBuilds(true, $event)">
<svg class="icon lg "><use xlink:href="#rocket"></use></svg><span class="button-lbl"> Builds</span>
<svg class="icon lg "><use xlink:href="#rocket"></use></svg><span class="button-lbl"> {{'builds' | translate}}</span>
</button>
<button class="r" ng-click="permalink($event)" ng-disabled="builds.length == 0">
<svg class="icon lg "><use xlink:href="#link"></use></svg><span class="button-lbl"> Permalink</span>
<svg class="icon lg "><use xlink:href="#link"></use></svg><span class="button-lbl"> {{'permalink' | translate}}</span>
</button>
<button class="r" ng-click="embed($event)" ng-disabled="builds.length == 0">
<svg class="icon lg "><use xlink:href="#embed"></use></svg><span class="button-lbl"> Forum</span>
<svg class="icon lg "><use xlink:href="#embed"></use></svg><span class="button-lbl"> {{'forum' | translate}}</span>
</button>
</td>
</tr>
<tr ng-show="!compareMode">
<td class="head">Comparison</td>
<td class="head" translate="comparison"></td>
<td>
<h3 ng-bind="name"></h3>
<button class="r" ui-sref="modal.import({obj:importObj})"><svg class="icon lg "><use xlink:href="#download"></use></svg> Import Builds</button>
<button class="r" ui-sref="modal.import({obj:importObj})"><svg class="icon lg "><use xlink:href="#download"></use></svg> {{'import' | translate}}</button>
</td>
</tr>
<tr>
<td class="head">Compare</td>
<td class="head" translate="compare"></td>
<td>
<ul id="facet-container" as-sortable="facetSortOpts" ng-model="facets" class="sortable" update="tblUpdate">
<li ng-repeat="(i,f) in facets" as-sortable-item class="facet" ng-class="{active: f.active}" ng-click="toggleFacet(i)">
<div as-sortable-item-handle>&#x2194; <span ng-bind="f.title"></span></div>
<div as-sortable-item-handle>&#x2194; <span ng-bind="f.title | translate"></span></div>
</li>
</ul>
</td>
@@ -43,15 +43,15 @@
</div>
<div ng-repeat="f in facets | filter:{active:true}" ng-if="builds.length > 0" class="chart" bar-chart facet="f" data="builds">
<h3 ng-click="sort(f.props[0])" >{{f.title}}</h3>
<h3 ng-click="sort(f.props[0])" >{{f.title | translate}}</h3>
</div>
<div class="modal-bg" ng-show="showBuilds" ng-click="selectBuilds(false, $event)">
<div class="modal" ui-view="modal-content" ng-click="$event.stopPropagation()">
<h3>Select Builds to Compare</h3>
<h3 translate="PHRASE_SELECT_BUILDS"></h3>
<div id="build-select">
<table>
<thead><tr><th colspan="2">Available</th></tr></thead>
<thead><tr><th colspan="2" translate="available"></th></tr></thead>
<tbody>
<tr ng-repeat="b in unusedBuilds | orderBy:'name'" ng-click="addBuild(b.id, b.buildName)">
<td class="tl" ng-bind="b.name"></td><td class="tl" ng-bind="b.buildName"></td>
@@ -60,7 +60,7 @@
</table>
<h1></h1>
<table>
<thead><tr><th colspan="2">Added</th></tr></thead>
<thead><tr><th colspan="2" translate="added"></th></tr></thead>
<tbody>
<tr ng-repeat="b in builds | orderBy:'name'" ng-click="removeBuild(b.id, b.buildName)">
<td class="tl" ng-bind="b.name"></td><td class="tl" ng-bind="b.buildName"></td>
@@ -69,6 +69,6 @@
</table>
</div>
<br>
<button class="r dismiss" ng-click="selectBuilds(false, $event)">Done</button>
<button class="r dismiss cap" ng-click="selectBuilds(false, $event)" translate="done"></button>
</div>
</div>

View File

@@ -3,27 +3,27 @@
<div id="overview">
<h1 ng-bind="ship.name"></h1>
<div id="build">
<input ng-model="buildName" ng-change="bnChange()" placeholder="Enter Build Name" maxsize="50" />
<input ng-model="buildName" ng-change="bnChange()" placeholder="{{'enter name' | translate}}" maxsize="50" />
<button ng-click="saveBuild()" ng-disabled="!buildName || savedCode && code == savedCode || !canSave">
<svg class="icon lg "><use xlink:href="#floppy-disk"></use></svg><span class="button-lbl">Save</span>
<svg class="icon lg "><use xlink:href="#floppy-disk"></use></svg><span class="button-lbl" translate="save"></span>
</button>
<button ng-click="reloadBuild()" ng-disabled="!savedCode || code == savedCode">
<svg class="icon lg"><use xlink:href="#spinner11"></use></svg><span class="button-lbl">Reload</span>
<svg class="icon lg"><use xlink:href="#spinner11"></use></svg><span class="button-lbl" translate="reload"></span>
</button>
<button class="danger" ng-click="deleteBuild()" ng-disabled="!savedCode">
<svg class="icon lg"><use xlink:href="#bin"></use></svg>
</button>
<button ui-sref="outfit({shipId: ship.id,code:null, bn: buildName})" ng-disabled="!code">
<svg class="icon lg"><use xlink:href="#switch"></use></svg><span class="button-lbl">Reset</span>
<svg class="icon lg"><use xlink:href="#switch"></use></svg><span class="button-lbl" translate="reset"></span>
</button>
<button ng-click="aRatedBuild()">
<svg class="icon lg"><use xlink:href="#a"></use></svg><span class="button-lbl">A-Rated</span>
<svg class="icon lg"><use xlink:href="#a"></use></svg><span class="button-lbl" translate="A-Rated"></span>
</button>
<button ng-click="optimizeMassBuild()">
<svg class="icon lg"><use xlink:href="#feather"></use></svg><span class="button-lbl">Optimize Mass</span>
<svg class="icon lg"><use xlink:href="#feather"></use></svg><span class="button-lbl" translate="optimize mass"></span>
</button>
<button ng-click="exportBuild($event)" ng-disabled="!buildName">
<svg class="icon lg"><use xlink:href="#download"></use></svg><span class="button-lbl">Export</span>
<svg class="icon lg"><use xlink:href="#download"></use></svg><span class="button-lbl" translate="export"></span>
</button>
</div>
</div>
@@ -32,42 +32,42 @@
<table id="summaryTable">
<thead>
<tr class="main">
<th rowspan="2">Size</th>
<th rowspan="2">Agility</th>
<th rowspan="2" ng-class="{'bg-warning-disabled': th.c.maxmass < ship.ladenMass}">Speed</th>
<th rowspan="2" ng-class="{'bg-warning-disabled': (pd.c.enginecapacity < ship.boostEnergy || th.c.maxmass < ship.ladenMass)}">Boost</th>
<th rowspan="2">DPS</th>
<th rowspan="2">Armour</th>
<th rowspan="2">Shields</th>
<th colspan="3">Mass</th>
<th rowspan="2">Cargo</th>
<th rowspan="2">Fuel</th>
<th colspan="3">Jump Range</th>
<th colspan="3">Total Range</th>
<th rowspan="2">Lock<br>Factor</th>
<th rowspan="2" translate="size"></th>
<th rowspan="2" translate="agility"></th>
<th rowspan="2" ng-class="{'bg-warning-disabled': th.c.maxmass < ship.ladenMass}" translate="speed"></th>
<th rowspan="2" ng-class="{'bg-warning-disabled': (pd.c.enginecapacity < ship.boostEnergy || th.c.maxmass < ship.ladenMass)}" translate="boost"></th>
<th rowspan="2" translate="DPS"></th>
<th rowspan="2" translate="armour"></th>
<th rowspan="2" translate="shields"></th>
<th colspan="3" translate="mass"></th>
<th rowspan="2" translate="cargo"></th>
<th rowspan="2" translate="fuel"></th>
<th colspan="3" translate="jump range"></th>
<th colspan="3" translate="total range"></th>
<th rowspan="2" translate="lock factor"></th>
</tr>
<tr>
<th class="lft">Hull</th>
<th>Unladen</th>
<th>Laden</th>
<th class="lft">Max</th>
<th>Full Tank</th>
<th>Laden</th>
<th class="lft">Jumps</th>
<th>Unladen</th>
<th>Laden</th>
<th class="lft" translate="hull"></th>
<th translate="unladen"></th>
<th translate="laden"></th>
<th class="lft" translate="max"></th>
<th translate="full tank"></th>
<th translate="laden"></th>
<th class="lft" translate="jumps"></th>
<th translate="unladen"></th>
<th translate="laden"></th>
</tr>
</thead>
<tbody>
<tr>
<td ng-bind="SZ[ship.class]"></td>
<td class="cap" ng-bind="['','small','medium','large','capital'][ship.class] | translate"></td>
<td>{{ship.agility}}/10</td>
<td>
<span ng-if="th.c.maxmass >= ship.ladenMass">{{fRound(ship.speed)}} <u>m/s</u></span>
<span ng-if="th.c.maxmass >= ship.ladenMass">{{fRound(ship.speed)}} <u translate>m/s</u></span>
<span class="warning" ng-if="th.c.maxmass < ship.ladenMass">0 <svg class="icon"><use xlink:href="#warning"></use></svg></span>
</td>
<td>
<span ng-if="pd.c.enginecapacity >= ship.boostEnergy && th.c.maxmass >= ship.ladenMass">{{fRound(ship.boost)}} <u>m/s</u></span>
<span ng-if="pd.c.enginecapacity >= ship.boostEnergy && th.c.maxmass >= ship.ladenMass">{{fRound(ship.boost)}} <u translate>m/s</u></span>
<span class="warning" ng-if="pd.c.enginecapacity < ship.boostEnergy || th.c.maxmass < ship.ladenMass">0
<svg class="icon"><use xlink:href="#warning"></use></svg>
</span>
@@ -75,21 +75,22 @@
<td>{{fRound(ship.totalDps)}}</td>
<td>
{{ship.armour}}
<span ng-if="ship.armourAdded || ship.armourMultiplier > 1">(<span ng-if="ship.armourMultiplier > 1">{{fRPct(ship.armourMultiplier)}}</span>
<span ng-if="ship.armourAdded">+ {{ship.armourAdded}}</span>)</span>
<span ng-if="ship.armourAdded || ship.armourMultiplier > 1">
(<span ng-if="ship.armourMultiplier > 1">{{fRPct(ship.armourMultiplier)}}</span><span ng-if="ship.armourAdded && ship.armourMultiplier > 1">&nbsp;</span><span ng-if="ship.armourAdded">+ {{ship.armourAdded}}</span>)
</span>
</td>
<td>{{fRound(ship.shieldStrength)}} <u>MJ</u> <span ng-if="ship.shieldMultiplier > 1 && ship.shieldStrength > 0">({{fRPct(ship.shieldMultiplier)}})</span></td>
<td>{{ship.hullMass}} <u>T</u></td>
<td>{{fRound(ship.unladenMass)}} <u>T</u></td>
<td>{{fRound(ship.ladenMass)}} <u>T</u></td>
<td>{{fRound(ship.cargoCapacity)}} <u>T</u></td>
<td>{{fRound(ship.fuelCapacity)}} <u>T</u></td>
<td>{{fRound(ship.unladenRange)}} <u>LY</u></td>
<td>{{fRound(ship.fullTankRange)}} <u>LY</u></td>
<td>{{fRound(ship.ladenRange)}} <u>LY</u></td>
<td>{{fRound(ship.shieldStrength)}} <u translate>MJ</u> <span ng-if="ship.shieldMultiplier > 1 && ship.shieldStrength > 0">({{fRPct(ship.shieldMultiplier)}})</span></td>
<td>{{ship.hullMass}} <u translate>T</u></td>
<td>{{fRound(ship.unladenMass)}} <u translate>T</u></td>
<td>{{fRound(ship.ladenMass)}} <u translate>T</u></td>
<td>{{fRound(ship.cargoCapacity)}} <u translate>T</u></td>
<td>{{fRound(ship.fuelCapacity)}} <u translate>T</u></td>
<td>{{fRound(ship.unladenRange)}} <u translate>LY</u></td>
<td>{{fRound(ship.fullTankRange)}} <u translate>LY</u></td>
<td>{{fRound(ship.ladenRange)}} <u translate>LY</u></td>
<td>{{fRound(ship.maxJumpCount)}}</td>
<td>{{fRound(ship.unladenTotalRange)}} <u>LY</u></td>
<td>{{fRound(ship.ladenTotalRange)}} <u>LY</u></td>
<td>{{fRound(ship.unladenTotalRange)}} <u translate>LY</u></td>
<td>{{fRound(ship.ladenTotalRange)}} <u translate>LY</u></td>
<td ng-bind="ship.masslock"></td>
</tr>
</tbody>
@@ -97,103 +98,103 @@
</div>
<div id="standard" class="group">
<h1>Standard</h1>
<h1 translate="standard"></h1>
<div class="slot" ng-click="selectSlot($event, ship.bulkheads)" ng-class="{selected: selectedSlot==ship.bulkheads}">
<div class="details">
<div class="sz"><span>8</span></div>
<div class="l">Bulkheads</div>
<div class="r">{{ship.bulkheads.c.mass}} <u>T</u></div>
<div class="cl l">{{ship.bulkheads.c.name}}</div>
<div class="l cap" translate="bh"></div>
<div class="r">{{ship.bulkheads.c.mass}} <u translate>T</u></div>
<div class="cl l">{{ship.bulkheads.c.name | translate}}</div>
</div>
<div class="select" ng-if="selectedSlot==ship.bulkheads" ng-click="select('b',ship.bulkheads,$event)">
<ul>
<li class="lc" ng-class="{active: ship.bulkheads.id=='0'}" cpid="0">Lightweight Alloy</li>
<li class="lc" ng-class="{active: ship.bulkheads.id=='1'}" cpid="1">Reinforced Alloy</li>
<li class="lc" ng-class="{active: ship.bulkheads.id=='2'}" cpid="2">Military Grade Composite</li>
<li class="lc" ng-class="{active: ship.bulkheads.id=='3'}" cpid="3">Mirrored Surface Composite</li>
<li class="lc" ng-class="{active: ship.bulkheads.id=='4'}" cpid="4">Reactive Surface Composite</li>
<li class="lc" ng-class="{active: ship.bulkheads.id=='0'}" cpid="0" translate="Lightweight Alloy"></li>
<li class="lc" ng-class="{active: ship.bulkheads.id=='1'}" cpid="1" translate="Reinforced Alloy"></li>
<li class="lc" ng-class="{active: ship.bulkheads.id=='2'}" cpid="2" translate="Military Grade Composite"></li>
<li class="lc" ng-class="{active: ship.bulkheads.id=='3'}" cpid="3" translate="Mirrored Surface Composite"></li>
<li class="lc" ng-class="{active: ship.bulkheads.id=='4'}" cpid="4" translate="Reactive Surface Composite"></li>
</ul>
</div>
</div>
<div class="slot" ng-click="selectSlot($event, pp)" ng-class="{selected: selectedSlot==pp}">
<div class="details" ng-class="{warning: pp.c.pGen < ship.powerRetracted}">
<div class="sz">{{::pp.maxClass}}</div>
<div class="l">{{pp.id}} Power Plant</div>
<div class="r">{{pp.c.mass}} <u>T</u></div>
<div class="l">{{pp.id}} {{'pp' | translate}}</div>
<div class="r">{{pp.c.mass}} <u translate>T</u></div>
<div class="cb"></div>
<div class="l">Efficiency: {{pp.c.eff}}</div>
<div class="l">Power: {{pp.c.pGen}} <u>MW</u></div>
<div class="l cap">{{'efficiency' | translate}}: {{pp.c.eff}}</div>
<div class="l cap">{{'power' | translate}}: {{pp.c.pGen}} <u translate>MW</u></div>
</div>
<div component-select class="select" s="pp" warning="ppWarning" opts="availCS.common[0]" ng-if="selectedSlot==pp" ng-click="select('c',pp,$event)"></div>
</div>
<div class="slot" ng-click="selectSlot($event, th)" ng-class="{selected: selectedSlot==th}">
<div class="details" ng-class="{'warning': th.c.maxmass < ship.ladenMass}">
<div class="sz">{{::th.maxClass}}</div>
<div class="l">{{th.id}} Thrusters</div>
<div class="r">{{th.c.mass}} <u>T</u></div>
<div class="l">{{th.id}} {{'t' | translate}}</div>
<div class="r">{{th.c.mass}} <u translate>T</u></div>
<div class="cb"></div>
<div class="l">Optimal Mass: {{th.c.optmass}} <u>T</u></div>
<div class="l">Max Mass: {{th.c.maxmass}} <u>T</u></div>
<div class="l">{{'optimal mass' | translate}}: {{th.c.optmass}} <u translate>T</u></div>
<div class="l">{{'max mass' | translate}}: {{th.c.maxmass}} <u translate>T</u></div>
</div>
<div component-select class="select" s="th" mass="ship.ladenMass" opts="availCS.common[1]" ng-if="selectedSlot==th" ng-click="select('c',th,$event)"></div>
</div>
<div class="slot" ng-click="selectSlot($event, fsd)" ng-class="{selected: selectedSlot==fsd}">
<div class="details">
<div class="sz">{{::fsd.maxClass}}</div>
<div class="l">{{fsd.id}} Frame Shift Drive</div>
<div class="r cr">{{fsd.c.mass}} <u>T</u></div>
<div class="l">{{fsd.id}} {{'fd' | translate}}</div>
<div class="r cr">{{fsd.c.mass}} <u translate>T</u></div>
<div class="cb"></div>
<div class="l">Optimal Mass: {{fsd.c.optmass}} <u>T</u></div>
<div class="l">Max Fuel: {{fsd.c.maxfuel}} <u>T</u></div>
<div class="l cap">{{'optimal mass' | translate}}: {{fsd.c.optmass}} <u translate>T</u></div>
<div class="l cap">{{'max mass' | translate}}: {{fsd.c.maxfuel}} <u translate>T</u></div>
</div>
<div component-select class="select" s="fsd" opts="availCS.common[2]" ng-if="selectedSlot==fsd" ng-click="select('c',fsd,$event)"></div>
</div>
<div class="slot" ng-click="selectSlot($event, ls)" ng-class="{selected: selectedSlot==ls}">
<div class="details">
<div class="sz">{{::ls.maxClass}}</div>
<div class="l">{{ls.id}} Life Support</div>
<div class="r">{{ls.c.mass}} <u>T</u></div>
<div class="l">{{ls.id}} {{'ls' | translate}}</div>
<div class="r">{{ls.c.mass}} <u translate>T</u></div>
<div class="cb"></div>
<div class="l">Time: {{fTime(ls.c.time)}}</div>
<div class="l cap">{{'time' | translate}}: {{fTime(ls.c.time)}}</div>
</div>
<div component-select class="select" s="ls" opts="availCS.common[3]" ng-if="selectedSlot==ls" ng-click="select('c',ls,$event)"></div>
</div>
<div class="slot" ng-click="selectSlot($event, pd)" ng-class="{selected: selectedSlot==pd}">
<div class="details" ng-class="{warning: pd.c.enginecapacity < ship.boostEnergy}">
<div class="sz">{{::pd.maxClass}}</div>
<div class="l">{{pd.id}} Power Distributor</div>
<div class="r">{{pd.c.mass}} <u>T</u></div>
<div class="l">{{pd.id}} {{'pd' | translate}}</div>
<div class="r">{{pd.c.mass}} <u translate>T</u></div>
<div class="cb"></div>
<div class="l">WEP: {{pd.c.weaponcapacity}} <u>MJ</u> / {{pd.c.weaponrecharge}} <u>MW</u></div>
<div class="l">SYS: {{pd.c.systemcapacity}} <u>MJ</u> / {{pd.c.systemrecharge}} <u>MW</u></div>
<div class="l">ENG: {{pd.c.enginecapacity}} <u>MJ</u> / {{pd.c.enginerecharge}} <u>MW</u></div>
<div class="l">{{'WEP' | translate}}: {{pd.c.weaponcapacity}} <u translate>MJ</u> / {{pd.c.weaponrecharge}} <u translate>MW</u></div>
<div class="l">{{'SYS' | translate}}: {{pd.c.systemcapacity}} <u translate>MJ</u> / {{pd.c.systemrecharge}} <u translate>MW</u></div>
<div class="l">{{'ENG' | translate}}: {{pd.c.enginecapacity}} <u translate>MJ</u> / {{pd.c.enginerecharge}} <u translate>MW</u></div>
</div>
<div component-select class="select" s="pd" warning="pdWarning" opts="availCS.common[4]" ng-if="selectedSlot==pd" ng-click="select('c',pd,$event)"></div>
</div>
<div class="slot" ng-click="selectSlot($event, ss)" ng-class="{selected: selectedSlot==ss}">
<div class="details">
<div class="sz">{{::ss.maxClass}}</div>
<div class="l">{{ss.id}} Sensors</div>
<div class="r">{{ss.c.mass}} <u>T</u></div>
<div class="l">{{ss.id}} {{'s' | translate}}</div>
<div class="r">{{ss.c.mass}} <u translate>T</u></div>
<div class="cb"></div>
<div class="l">Range: {{ss.c.range}} <u>km</u></div>
<div class="l cap">{{'range' | translate}}: {{ss.c.range}} <u translate>km</u></div>
</div>
<div component-select class="select" s="ss" opts="availCS.common[5]" ng-if="selectedSlot==ss" ng-click="select('c',ss,$event)"></div>
</div>
<div class="slot" ng-click="selectSlot($event, ft)" ng-class="{selected: selectedSlot==ft}">
<div class="details">
<div class="sz">{{::ft.maxClass}}</div>
<div class="l">{{ft.id}} Fuel Tank</div>
<div class="r">{{ft.c.capacity}} <u>T</u></div>
<div class="l">{{ft.id}} {{'ft' | translate}}</div>
<div class="r">{{ft.c.capacity}} <u translate>T</u></div>
</div>
<div component-select class="select" s="ft" opts="availCS.common[6]" ng-if="selectedSlot==ft" ng-click="select('c',ft,$event)"></div>
</div>
</div>
<div id="internal" class="group">
<h1>Internal Compartments</h1>
<h1 translate="internal compartments"></h1>
<div class="slot" ng-repeat="i in ship.internal" ng-click="selectSlot($event, i)" context-menu="select('i', i, $event, 'empty')" ng-class="{selected: selectedSlot==i}">
<div slot-internal class="details" slot="i" lbl="GMAP[i.c.grp]" fuel="ship.fuelCapacity"></div>
<div slot-internal class="details" slot="i" fuel="ship.fuelCapacity"></div>
<div class="select" ng-if="selectedSlot==i" ng-click="select('i',i,$event)">
<div component-select s="i" groups="availCS.getInts(i.maxClass, i.eligible)"></div>
</div>
@@ -201,9 +202,9 @@
</div>
<div id="hardpoints" class="group">
<h1>HardPoints</h1>
<h1 translate="hardpoints"></h1>
<div class="slot" ng-repeat="h in ship.hardpoints | filter:{maxClass: '!0'}" ng-click="selectSlot($event, h)" context-menu="select('h', h, $event, 'empty')" ng-class="{selected: selectedSlot==h}">
<div slot-hardpoint class="details" hp="h" size="HPC[h.maxClass]" lbl="GMAP[h.c.grp]"></div>
<div slot-hardpoint class="details" hp="h" size="HPC[h.maxClass]"></div>
<div class="select" ng-class="{hardpoint: h.maxClass > 0}" ng-if="selectedSlot==h" ng-click="select('h',h,$event)">
<div component-select s="h" groups="availCS.getHps(h.maxClass)"></div>
</div>
@@ -211,9 +212,9 @@
</div>
<div id="utility" class="group">
<h1>Utility Mounts</h1>
<h1 translate="utility mounts"></h1>
<div class="slot" ng-repeat="h in ship.hardpoints | filter:{maxClass: '0'}" ng-click="selectSlot($event, h)" context-menu="select('h', h, $event, 'empty')" ng-class="{selected: selectedSlot==h}">
<div slot-hardpoint class="details" hp="h" size="HPC[h.maxClass]" lbl="GMAP[h.c.grp]"></div>
<div slot-hardpoint class="details" hp="h" size="HPC[h.maxClass]"></div>
<div class="select" ng-class="{hardpoint: h.maxClass > 0}" ng-if="selectedSlot==h" ng-click="select('h',h,$event)">
<div component-select s="h" groups="availCS.getHps(h.maxClass)"></div>
</div>
@@ -224,19 +225,19 @@
<table style="width:100%">
<thead>
<tr class="main">
<th colspan="2" class="sortable le" ng-click="sortPwr(cName)">Component</th>
<th style="width:3em;" class="sortable" ng-click="sortPwr('type')">Type</th>
<th style="width:4em;" class="sortable" ng-click="sortPwr('priority')">Pri</th>
<th colspan="2" class="sortable" ng-click="sortPwr('c.power')">Pwr</th>
<th style="width:3em;" class="sortable" ng-click="sortPwr(statusRetracted)">Ret</th>
<th style="width:3em;" class="sortable" ng-click="sortPwr(statusDeployed)">Dep</th>
<th colspan="2" class="sortable le" ng-click="sortPwr(cName)" translate="COMPONENT"></th>
<th style="width:3em;" class="sortable" ng-click="sortPwr('type')" translate="TYPE"></th>
<th style="width:4em;" class="sortable" ng-click="sortPwr('priority')" translate="PRI"></th>
<th colspan="2" class="sortable" ng-click="sortPwr('c.power')" translate="PWR"></th>
<th style="width:3em;" class="sortable" ng-click="sortPwr(statusRetracted)" translate="RET"></th>
<th style="width:3em;" class="sortable" ng-click="sortPwr(statusDeployed)" translate="DEP"></th>
</tr>
</thead>
<tbody>
<tr>
<td>{{pp.c.class}}{{pp.c.rating}}</td>
<td class="le shorten">Power Plant</td>
<td><u>SYS</u></td>
<td class="le shorten cap" translate="pp"></td>
<td><u translate="SYS"></u></td>
<td>1</td>
<td class="ri">{{fPwr(pp.c.pGen)}}</td>
<td class="ri"><u>100%</u></td>
@@ -246,14 +247,14 @@
<tr><td style="line-height:0;" colspan="8"><hr style="margin: 0 0 3px;background: #ff8c0d;border: 0;height: 1px;" /></td></tr>
<tr class="highlight" ng-repeat="c in powerList | orderBy:pwrPredicate:pwrDesc" ng-if="c.c.power" ng-class="{disabled:!c.enabled}">
<td style="width:1em;" ng-click="togglePwr(c)">{{c.c.class}}{{c.c.rating}}</td>
<td class="le shorten" ng-click="togglePwr(c)" ng-bind="cName(c)"></td>
<td ng-click="togglePwr(c)"><u ng-bind="c.type"></u></td>
<td class="le shorten cap" ng-click="togglePwr(c)" ng-bind="cName(c)"></td>
<td ng-click="togglePwr(c)"><u ng-bind="c.type | translate"></u></td>
<td><span ng-click="decPriority(c)" class="flip">&#9658;</span> {{c.priority + 1}} <span ng-click="incPriority(c)">&#9658;</span></td>
<td class="ri" style="width:3.25em;">{{fPwr(c.c.power)}}</td>
<td class="ri" style="width:3em;"><u>{{f1Pct(c.c.power/ship.powerAvailable)}}</u></td>
<td ng-if="!c.enabled" class="disabled" colspan="2">DISABLED</td>
<td ng-if="c.enabled" ng-class="STATUS_CLASS[statusRetracted(c)]">{{STATUS[statusRetracted(c)]}}</td>
<td ng-if="c.enabled" ng-class="STATUS_CLASS[statusDeployed(c)]">{{STATUS[statusDeployed(c)]}}</td>
<td ng-if="!c.enabled" class="disabled upp" colspan="2" translate="disabled"></td>
<td class="upp" ng-if="c.enabled" ng-class="STATUS_CLASS[statusRetracted(c)]">{{STATUS[statusRetracted(c)] | translate}}</td>
<td class="upp" ng-if="c.enabled" ng-class="STATUS_CLASS[statusDeployed(c)]">{{STATUS[statusDeployed(c)] | translate}}</td>
</tr>
</tbody>
</table>
@@ -264,8 +265,8 @@
<table class="tabs">
<thead>
<tr>
<th style="width:50%" ng-class="{active: costTab == 'retrofit'}" ng-click="updateCostTab('retrofit')">Retrofit Costs</th>
<th style="width:50%" ng-class="{active: costTab == 'costs'}" ng-click="updateCostTab('costs')">Costs</th>
<th style="width:50%" ng-class="{active: costTab == 'retrofit'}" ng-click="updateCostTab('retrofit')" translate="retrofit costs"></th>
<th style="width:50%" ng-class="{active: costTab == 'costs'}" ng-click="updateCostTab('costs')" translate="costs"></th>
</tr>
</thead>
</table>
@@ -275,29 +276,29 @@
<thead>
<tr class="main">
<th colspan="2" class="sortable le" ng-click="sortCost(cName)">
Component
<u class="optional-hide" ng-if="discounts.ship < 1">[Ship {{fRPct(1 - discounts.ship)}} off]</u>
<u class="optional-hide" ng-if="discounts.components < 1">[Components {{fRPct(1 - discounts.components)}} off]</u>
{{'component' | translate}}
<u class="optional-hide" ng-if="discounts.ship < 1">[{{'ship' | translate }} -{{fRPct(1 - discounts.ship)}}]</u>
<u class="optional-hide" ng-if="discounts.components < 1">[{{'components' | translate}} -{{fRPct(1 - discounts.components)}}]</u>
</th>
<th class="sortable le" ng-click="sortCost('discountedCost')">Credits</th>
<th class="sortable le" ng-click="sortCost('discountedCost')" translate="credits"></th>
</tr>
</thead>
<tbody>
<tr class="highlight" ng-repeat="item in costList | orderBy:costPredicate:costDesc" ng-if="item.c.cost > 0" ng-class="{disabled:!item.incCost}">
<td class="toggleable" style="width:1em;" ng-click="toggleCost(item)">{{item.c.class}}{{item.c.rating}}</td>
<td class="le toggleable shorten" ng-click="toggleCost(item)">{{cName(item)}}</td>
<td class="ri toggleable" ng-click="toggleCost(item)">{{fCrd(item.discountedCost)}} <u>CR</u></td>
<td class="le toggleable shorten cap" ng-click="toggleCost(item)">{{cName(item)}}</td>
<td class="ri toggleable" ng-click="toggleCost(item)">{{fCrd(item.discountedCost)}} <u translate>CR</u></td>
</tr>
</tbody>
</table>
<table class="total">
<tr class="ri">
<td class="lbl">Total</td>
<td>{{fCrd(ship.totalCost)}} <u>CR</u></td>
<td class="lbl" translate="total"></td>
<td>{{fCrd(ship.totalCost)}} <u translate>CR</u></td>
</tr>
<tr class="ri">
<td class="lbl">Insurance</td>
<td>{{fCrd(ship.totalCost * insurance.current.pct)}} <u>CR</u></td>
<td class="lbl" translate="insurance"></td>
<td>{{fCrd(ship.totalCost * insurance.current.pct)}} <u translate>CR</u></td>
</tr>
</table>
</div>
@@ -307,38 +308,38 @@
<table style="width:100%">
<thead>
<tr class="main">
<th colspan="2" class="sortable le" ng-click="sortRetrofit('sellName')">Sell</th>
<th colspan="2" class="sortable le" ng-click="sortRetrofit('buyName')">Buy</th>
<th colspan="2" class="sortable le" ng-click="sortRetrofit('sellName | translate')" translate="sell"></th>
<th colspan="2" class="sortable le" ng-click="sortRetrofit('buyName | translate')" translate="buy"></th>
<th class="sortable le" ng-click="sortRetrofit('netCost')">
Net Cost <u class="optional-hide" ng-if="discounts.components < 1">[{{fRPct(1 - discounts.components)}} off]</u>
{{'net cost' | translate}} <u class="optional-hide" ng-if="discounts.components < 1">-[{{fRPct(1 - discounts.components)}}]</u>
</th>
</tr>
</thead>
<tbody>
<tr ng-if="!retrofitList || retrofitList.length == 0">
<td colspan="5" style="padding: 3em 0;">No Retrofitting changes</td>
<td colspan="5" style="padding: 3em 0;" translate="PHRASE_NO_RETROCH"></td>
</tr>
<tr class="highlight" ng-repeat="item in retrofitList | orderBy:retroPredicate:retroDesc">
<td style="width:1em;">{{item.sellClassRating}}</td>
<td class="le shorten">{{item.sellName}}</td>
<td class="le shorten cap">{{item.sellName | translate}}</td>
<td style="width:1em;">{{item.buyClassRating}}</td>
<td class="le shorten">{{item.buyName}}</td>
<td class="ri" ng-class="item.netCost > 0 ? 'warning' : 'secondary-disabled'">{{ fCrd(item.netCost)}} <u>CR</u></td>
<td class="le shorten cap">{{item.buyName | translate}}</td>
<td class="ri" ng-class="item.netCost > 0 ? 'warning' : 'secondary-disabled'">{{ fCrd(item.netCost)}} <u translate>CR</u></td>
</tr>
</tbody>
</table>
</div>
<table class="total">
<tr class="ri">
<td class="lbl">Cost</td>
<td colspan="2" ng-class="retrofitTotal > 0 ? 'warning' : 'secondary-disabled'">{{fCrd(retrofitTotal)}} <u>CR</u></td>
<td class="lbl" translate="cost"></td>
<td colspan="2" ng-class="retrofitTotal > 0 ? 'warning' : 'secondary-disabled'">{{fCrd(retrofitTotal)}} <u translate>CR</u></td>
</tr>
<tr class="ri">
<td class="lbl">Retrofit from</td>
<td class="lbl cap" translate="retrofit from"></td>
<td class="cen" style="border-right:none;width: 1em;"><u class="primary-disabled">&#9662;</u></td>
<td style="border-left:none;padding:0;">
<select style="width: 100%;padding: 0" ng-model="$parent.retrofitBuild" ng-change="setRetrofitBase()" ng-options="name as name for (name, build) in allBuilds[ship.id]">
<option value="">Stock / Standard</option>
<option value="">{{'Stock' | translate}}</option>
</select>
</td>
@@ -348,18 +349,18 @@
</div>
<div class="group half">
<h1>Jump Range</h1>
<h1 translate="jump range"></h1>
<div line-chart config="jrChart" series="jrSeries"></div>
</div>
<div class="group half">
<h1>Total Range</h1>
<h1 translate="total range"></h1>
<div line-chart config="trChart" series="trSeries"></div>
</div>
<!-- TODO: Add back in once calcSpeed is dynamic and accurate
<div class="group third">
<h1>Thruster Speed</h1>
<h1 translate="speed"></h1>
<div line-chart config="speedChart" series="speedSeries"></div>
</div>
-->

View File

@@ -26,7 +26,8 @@
"d3-tip": "~0.6.7",
"ng-sortable": "~1.2.1",
"lz-string": "~1.4.4",
"angular": "~1.4.0"
"angular": "~1.4.0",
"angular-translate": "~2.7.2"
},
"overrides": {
"angular": {
@@ -35,6 +36,9 @@
"angular-ui-router": {
"main": "release/angular-ui-router.min.js"
},
"angular-translate": {
"main": "angular-translate.min.js"
},
"d3": {
"main": "d3.min.js"
},

View File

@@ -1,6 +1,6 @@
{
"6E": {
"grp": "fsd",
"grp": "fd",
"class": 6,
"rating": "E",
"cost": 199747,
@@ -12,7 +12,7 @@
"fuelpower": 2.6
},
"6D": {
"grp": "fsd",
"grp": "fd",
"class": 6,
"rating": "D",
"cost": 599242,
@@ -24,7 +24,7 @@
"fuelpower": 2.6
},
"6C": {
"grp": "fsd",
"grp": "fd",
"class": 6,
"rating": "C",
"cost": 1797726,
@@ -36,7 +36,7 @@
"fuelpower": 2.6
},
"6B": {
"grp": "fsd",
"grp": "fd",
"class": 6,
"rating": "B",
"cost": 5393177,
@@ -48,7 +48,7 @@
"fuelpower": 2.6
},
"6A": {
"grp": "fsd",
"grp": "fd",
"class": 6,
"rating": "A",
"cost": 16179531,
@@ -60,7 +60,7 @@
"fuelpower": 2.6
},
"5E": {
"grp": "fsd",
"grp": "fd",
"class": 5,
"rating": "E",
"cost": 63013,
@@ -72,7 +72,7 @@
"fuelpower": 2.45
},
"5D": {
"grp": "fsd",
"grp": "fd",
"class": 5,
"rating": "D",
"cost": 189036,
@@ -84,7 +84,7 @@
"fuelpower": 2.45
},
"5C": {
"grp": "fsd",
"grp": "fd",
"class": 5,
"rating": "C",
"cost": 567106,
@@ -96,7 +96,7 @@
"fuelpower": 2.45
},
"5B": {
"grp": "fsd",
"grp": "fd",
"class": 5,
"rating": "B",
"cost": 1701318,
@@ -108,7 +108,7 @@
"fuelpower": 2.45
},
"5A": {
"grp": "fsd",
"grp": "fd",
"class": 5,
"rating": "A",
"cost": 5103953,
@@ -120,7 +120,7 @@
"fuelpower": 2.45
},
"4E": {
"grp": "fsd",
"grp": "fd",
"class": 4,
"rating": "E",
"cost": 19878,
@@ -132,7 +132,7 @@
"fuelpower": 2.3
},
"4D": {
"grp": "fsd",
"grp": "fd",
"class": 4,
"rating": "D",
"cost": 59633,
@@ -144,7 +144,7 @@
"fuelpower": 2.3
},
"4C": {
"grp": "fsd",
"grp": "fd",
"class": 4,
"rating": "C",
"cost": 178898,
@@ -156,7 +156,7 @@
"fuelpower": 2.3
},
"4B": {
"grp": "fsd",
"grp": "fd",
"class": 4,
"rating": "B",
"cost": 536693,
@@ -168,7 +168,7 @@
"fuelpower": 2.3
},
"4A": {
"grp": "fsd",
"grp": "fd",
"class": 4,
"rating": "A",
"cost": 1610080,
@@ -180,7 +180,7 @@
"fuelpower": 2.3
},
"3E": {
"grp": "fsd",
"grp": "fd",
"class": 3,
"rating": "E",
"cost": 6271,
@@ -192,7 +192,7 @@
"fuelpower": 2.15
},
"3D": {
"grp": "fsd",
"grp": "fd",
"class": 3,
"rating": "D",
"cost": 18812,
@@ -204,7 +204,7 @@
"fuelpower": 2.15
},
"3C": {
"grp": "fsd",
"grp": "fd",
"class": 3,
"rating": "C",
"cost": 56435,
@@ -216,7 +216,7 @@
"fuelpower": 2.15
},
"3B": {
"grp": "fsd",
"grp": "fd",
"class": 3,
"rating": "B",
"cost": 169304,
@@ -228,7 +228,7 @@
"fuelpower": 2.15
},
"3A": {
"grp": "fsd",
"grp": "fd",
"class": 3,
"rating": "A",
"cost": 507912,
@@ -240,7 +240,7 @@
"fuelpower": 2.15
},
"2E": {
"grp": "fsd",
"grp": "fd",
"class": 2,
"rating": "E",
"cost": 1978,
@@ -252,7 +252,7 @@
"fuelpower": 2
},
"2D": {
"grp": "fsd",
"grp": "fd",
"class": 2,
"rating": "D",
"cost": 5934,
@@ -264,7 +264,7 @@
"fuelpower": 2
},
"2C": {
"grp": "fsd",
"grp": "fd",
"class": 2,
"rating": "C",
"cost": 17803,
@@ -276,7 +276,7 @@
"fuelpower": 2
},
"2B": {
"grp": "fsd",
"grp": "fd",
"class": 2,
"rating": "B",
"cost": 53408,
@@ -288,7 +288,7 @@
"fuelpower": 2
},
"2A": {
"grp": "fsd",
"grp": "fd",
"class": 2,
"rating": "A",
"cost": 160224,

View File

@@ -1,5 +1,5 @@
{
"Beam Laser": [
"bl": [
{
"id": "0u",
"grp": "bl",

View File

@@ -1,5 +1,5 @@
{
"Burst Laser": [
"ul": [
{
"id": "14",
"grp": "ul",

View File

@@ -1,5 +1,5 @@
{
"Cannon": [
"c": [
{
"id": "1q",
"grp": "c",

View File

@@ -1,5 +1,5 @@
{
"Cargo Scanner": [
"cs": [
{
"id": "0d",
"grp": "cs",

View File

@@ -1,5 +1,5 @@
{
"Countermeasure": [
"cm": [
{
"id": "00",
"grp": "cm",

View File

@@ -1,5 +1,5 @@
{
"Fragment Cannon": [
"fc": [
{
"id": "1t",
"grp": "fc",

View File

@@ -1,5 +1,5 @@
{
"Frame Shift Wake Scanner": [
"ws": [
{
"id": "0i",
"grp": "ws",

View File

@@ -1,5 +1,5 @@
{
"Kill Warrant Scanner": [
"kw": [
{
"id": "0n",
"grp": "kw",

View File

@@ -1,5 +1,5 @@
{
"Mine Launcher": [
"nl": [
{
"id": "2j",
"grp": "nl",

View File

@@ -1,5 +1,5 @@
{
"Mining Laser": [
"ml": [
{
"id": "2l",
"grp": "ml",

View File

@@ -1,5 +1,5 @@
{
"Missile Rack": [
"mr": [
{
"id": "2f",
"grp": "mr",

View File

@@ -1,5 +1,5 @@
{
"Multi-cannon": [
"mc": [
{
"id": "26",
"grp": "mc",

View File

@@ -1,5 +1,5 @@
{
"Plasma Accelerator": [
"pa": [
{
"id": "1g",
"grp": "pa",

View File

@@ -1,5 +1,5 @@
{
"Pulse Laser": [
"pl": [
{
"id": "1d",
"grp": "pl",

View File

@@ -1,5 +1,5 @@
{
"Rail Gun": [
"rg": [
{
"id": "29",
"grp": "rg",

View File

@@ -1,5 +1,5 @@
{
"Shield Booster": [
"sb": [
{
"id": "08",
"grp": "sb",

View File

@@ -1,5 +1,5 @@
{
"Torpedo Pylon": [
"tp": [
{
"id": "2h",
"grp": "tp",

View File

@@ -1,5 +1,5 @@
{
"Auto Field-Maintenance Unit": [
"am": [
{
"id": "1f",
"grp": "am",

View File

@@ -1,5 +1,5 @@
{
"Cargo Rack": [
"cr": [
{ "id": "00", "grp": "cr", "class": 1, "rating": "E", "cost": 1000, "capacity": 2 },
{ "id": "01", "grp": "cr", "class": 2, "rating": "E", "cost": 3250, "capacity": 4 },
{ "id": "02", "grp": "cr", "class": 3, "rating": "E", "cost": 10563, "capacity": 8 },

View File

@@ -1,5 +1,5 @@
{
"Collector Limpet Controller": [
"cc": [
{ "id": "Cf", "grp":"cc", "class":7, "rating":"E", "cost": 437400, "mass": 32.0, "power":0.41, "range":1.36, "maximum": 4, "time":300 },
{ "id": "Cg", "grp":"cc", "class":7, "rating":"D", "cost": 874800, "mass": 32.0, "power":0.55, "range":1.02, "maximum": 4, "time":600 },
{ "id": "Ch", "grp":"cc", "class":7, "rating":"C", "cost":1749600, "mass": 80.0, "power":0.69, "range":1.70, "maximum": 4, "time":510 },

View File

@@ -1,5 +1,5 @@
{
"Docking Computer": [
"dc": [
{
"id": "24",
"grp": "dc",

View File

@@ -1,5 +1,5 @@
{
"FSD Interdictor": [
"fi": [
{
"id": "6p",
"grp": "fi",

View File

@@ -1,5 +1,5 @@
{
"Fuel Scoop": [
"fs": [
{
"id": "3q",
"grp": "fs",

View File

@@ -1,5 +1,5 @@
{
"Fuel Transfer Limpet Controller": [
"fx": [
{ "id": "Ff", "grp":"fx", "class":7, "rating":"E", "cost": 437400, "mass": 80.0, "power":0.55, "range":1.02, "maximum": 8 },
{ "id": "Fg", "grp":"fx", "class":7, "rating":"D", "cost": 874800, "mass": 32.0, "power":0.41, "range":1.36, "maximum": 8 },
{ "id": "Fh", "grp":"fx", "class":7, "rating":"C", "cost":1749600, "mass": 80.0, "power":0.69, "range":1.70, "maximum": 8 },

View File

@@ -1,5 +1,5 @@
{
"Hatch Breaker Limpet Controller": [
"hb": [
{
"id": "7d",
"grp": "hb",

View File

@@ -1,5 +1,5 @@
{
"Hull Reinforcement Package": [
"hr": [
{
"id": "2e",
"grp": "hr",

View File

@@ -1,5 +1,5 @@
{
"Fuel Tank": [
"ft": [
{ "id": "f1", "grp": "ft", "class": 1, "rating": "C", "cost": 1000, "capacity": 2 },
{ "id": "f2", "grp": "ft", "class": 2, "rating": "C", "cost": 3750, "capacity": 4 },
{ "id": "f3", "grp": "ft", "class": 3, "rating": "C", "cost": 7063, "capacity": 8 },

View File

@@ -1,5 +1,5 @@
{
"Prismatic Shield Generator": [
"psg": [
{ "id": "p6", "grp": "psg", "class": 1, "rating": "A", "cost": 132195, "mass": 2.5, "power": 2.52, "minmass": 13, "optmass": 25, "maxmass": 63, "minmul": 2.04, "optmul": 1.44, "maxmul": 0.84 },
{ "id": "p5", "grp": "psg", "class": 2, "rating": "A", "cost": 240336, "mass": 5, "power": 3.15, "minmass": 23, "optmass": 55, "maxmass": 138, "minmul": 2.04, "optmul": 1.44, "maxmul": 0.84 },
{ "id": "p4", "grp": "psg", "class": 3, "rating": "A", "cost": 761868, "mass": 10, "power": 3.78, "minmass": 83, "optmass": 165, "maxmass": 413, "minmul": 2.04, "optmul": 1.44, "maxmul": 0.84 },

View File

@@ -1,5 +1,5 @@
{
"Prospector Limpet Controller": [
"pc": [
{ "id": "Pf", "grp":"pc", "class":7, "rating":"E", "cost": 437400, "mass": 80.0, "power":0.55, "range": 5.10, "maximum": 8 },
{ "id": "Pg", "grp":"pc", "class":7, "rating":"D", "cost": 874800, "mass": 32.0, "power":0.41, "range": 6.80, "maximum": 8 },
{ "id": "Ph", "grp":"pc", "class":7, "rating":"C", "cost":1749600, "mass": 80.0, "power":0.69, "range": 8.50, "maximum": 8 },

View File

@@ -1,5 +1,5 @@
{
"Refinery": [
"rf": [
{
"id": "23",
"grp": "rf",

View File

@@ -1,5 +1,5 @@
{
"Scanner": [
"sc": [
{
"id": "2f",
"grp": "sc",

View File

@@ -1,5 +1,5 @@
{
"Shield Cell Bank": [
"scb": [
{ "id": "65", "grp": "scb", "class": 8, "rating": "E", "cost": 697584, "mass": 160, "power": 1.44, "cells": 6, "rechargeRating": "C", "recharge": 0 },
{ "id": "64", "grp": "scb", "class": 8, "rating": "D", "cost": 1743961, "mass": 64, "power": 1.92, "cells": 4, "rechargeRating": "C", "recharge": 0 },
{ "id": "63", "grp": "scb", "class": 8, "rating": "C", "cost": 4359903, "mass": 160, "power": 2.4, "cells": 5, "rechargeRating": "B", "recharge": 0 },

View File

@@ -1,5 +1,5 @@
{
"Shield Generator": [
"sg": [
{ "id": "4t", "grp": "sg", "class": 8, "rating": "E", "cost": 2007241, "mass": 160, "power": 2.4, "minmass": 900, "optmass": 1800, "maxmass": 4500, "minmul": 1.3, "optmul": 0.8, "maxmul": 0.3 },
{ "id": "4s", "grp": "sg", "class": 8, "rating": "D", "cost": 6021722, "mass": 64, "power": 3.2, "minmass": 900, "optmass": 1800, "maxmass": 4500, "minmul": 1.4, "optmul": 0.9, "maxmul": 0.4 },
{ "id": "4r", "grp": "sg", "class": 8, "rating": "C", "cost": 18065165, "mass": 160, "power": 4, "minmass": 900, "optmass": 1800, "maxmass": 4500, "minmul": 1.5, "optmul": 1, "maxmul": 0.5 },

View File

@@ -30,23 +30,23 @@ function writeDB(err, arr) {
var shipOrder = Object.keys(arr[0]).sort();
var internalOrder = Object.keys(arr[3]).sort();
var hpOrder = [
"Pulse Laser",
"Burst Laser",
"Beam Laser",
"Multi-cannon",
"Cannon",
"Fragment Cannon",
"Rail Gun",
"Plasma Accelerator",
"Missile Rack",
"Torpedo Pylon",
"Mine Launcher",
"Mining Laser",
"Cargo Scanner",
"Countermeasure",
"Frame Shift Wake Scanner",
"Kill Warrant Scanner",
"Shield Booster"
"pl",
"ul",
"bl",
"mc",
"c",
"fc",
"rg",
"pa",
"mr",
"tp",
"nl",
"ml",
"cs",
"cm",
"ws",
"kw",
"sb"
];
for (var i = 0; i < internalOrder.length; i++) {