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

@@ -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. discounts = { opts: Discounts };
$rootScope.STATUS = ['', 'DISABLED', 'OFF', 'ON'];
$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_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

@@ -7,7 +7,7 @@
* @requires ngLodash
*/
angular.module('shipyard', ['ngLodash'])
// Create 'angularized' references to DB.This will aid testing
// Create 'angularized' references to DB. This will aid testing
.constant('ShipsDB', DB.ships)
.constant('ComponentsDB', DB.components)
.value('ArmourMultiplier', [
@@ -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 {