Merge branch 'develop' into ed-forge

This commit is contained in:
Felix Linker
2021-12-28 18:58:52 +01:00
27 changed files with 1915 additions and 1703 deletions

View File

@@ -1,77 +0,0 @@
node_modules
npm-debug.log
### Node template
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless

View File

@@ -1,13 +0,0 @@
image: docker:stable
services:
- docker:dind
stages:
- Build image
docker build:
stage: Build image
script:
- img build --build-arg branch=$CI_COMMIT_REF_NAME -t edcd/coriolis:$CI_COMMIT_REF_NAME .
- echo "$REGISTRY_PASSWORD" | img login --username "$REGISTRY_USER" --password-stdin
- img push edcd/coriolis:$CI_COMMIT_REF_NAME

View File

@@ -1,16 +0,0 @@
language: node_js
notifications:
email: false
sudo: false
node_js:
- "4.8.1"
cache:
directories:
- node_modules
before_install:
- git clone https://github.com/EDCD/coriolis-data.git ../coriolis-data
script:
- npm run lint
- npm test

View File

@@ -1,35 +0,0 @@
### STAGE 1: Build ###
FROM node:9.11.1-alpine as builder
ARG branch=develop
ENV BRANCH=$branch
WORKDIR /src/app
RUN mkdir -p /src/app/coriolis
RUN mkdir -p /src/app/coriolis-data
RUN apk add --update git
COPY . /src/app/coriolis
RUN npm i -g npm
# Set up coriolis-data
WORKDIR /src/app/coriolis-data
RUN git clone https://github.com/EDCD/coriolis-data.git .
RUN git checkout ${BRANCH}
RUN npm install --no-package-lock
RUN npm start
# Set up coriolis
WORKDIR /src/app/coriolis
RUN git checkout ${BRANCH}
RUN npm install --no-package-lock
RUN npm run build
### STAGE 2: Production Environment ###
FROM fholzer/nginx-brotli as web
COPY nginx.conf /etc/nginx/nginx.conf
COPY --from=builder /src/app/coriolis/build /usr/share/nginx/html
WORKDIR /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-c", "/etc/nginx/nginx.conf", "-g", "daemon off;"]

View File

@@ -1,4 +1,4 @@
![Latest Release](https://img.shields.io/github/release/EDCD/coriolis.svg) [![Build Status](https://travis-ci.org/EDCD/coriolis.svg?branch=master)](https://travis-ci.org/EDCD/coriolis) [![Chat to us on Discord](https://img.shields.io/badge/Discord-EDCD%20%23coriolis-blue.svg?style=social)](https://discord.gg/0uwCh6R62aPRjk9w)
[![Chat to us on Discord](https://img.shields.io/badge/Discord-EDCD%20%23coriolis-blue.svg?style=social)](https://discord.gg/0uwCh6R62aPRjk9w)
## About
@@ -8,53 +8,41 @@ Coriolis was created using assets and imagery from Elite: Dangerous, with the pe
## Contributing
Please [submit issues](https://github.com/EDCD/coriolis/issues), or better yet [pull requests](https://github.com/EDCD/coriolis/pulls) for any corrections or additions to the database or the code.
### Translations
Please use the OneSky translation site to suggest new translations: http://edcd-coriolis.oneskyapp.com
These will be merged regularly by the project manager.
### Feature Requests, Suggestions & Bugs
Chat to us on [Discord](https://discord.gg/0uwCh6R62aPRjk9w)!
- [Submit issues](https://github.com/EDCD/coriolis/issues)
- [Submit pull requests](https://github.com/EDCD/coriolis/pulls) targetting `develop` branch
- Chat to us on [Discord](https://discord.gg/0uwCh6R62aPRjk9w)!
## Development
See the [Developer's Guide](https://github.com/EDCD/coriolis/wiki/Developing-for-Coriolis) in the wiki.
To get a local instance of coriolis running, perform the following steps in a shell:
```sh
> git clone https://github.com/EDCD/coriolis.git
> git clone https://github.com/EDCD/coriolis-data.git
> cd ./coriolis-data
> npm install
> cd ../coriolis
> npm install
> npm start
```
Also see [the documentation site.](https://coriolis.willb.info/)
You will then have a development server running on `localhost:3300`.
### Ship and Module Database
See the [Data wiki](https://github.com/cmmcleod/coriolis-data/wiki) for details on structure, etc.
You can find hosted and compiled versions of these data-jsons under https://coriolis.io/data/ and https://beta.coriolis.io/data/.
You might want to load these as depedency instead of reyling on the npm-dependency.
## Deployment
## License
Follow the steps for [Development](#development) as above, but instead
of `npm start` you'll want to:
All Data and [associated JSON](https://github.com/EDCD/coriolis-data) files are intellectual property and copyright of Frontier Developments plc ('Frontier', 'Frontier Developments') and are subject to their
[terms and conditions](https://www.frontierstore.net/terms-and-conditions/).
```sh
> npm run build
```
The code (Javascript, CSS, HTML, and SVG files only) specificially for Coriolis.io is released under the MIT License.
this will result in a `build/` directory being created containing all the necessary files.
Copyright (c) 2015 Coriolis.io, Colin McLeod
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software (Javascript, CSS, HTML, and SVG files only), and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
After this you need to serve the files in some manner.
Either configure your webserver to make the actual `build/` directory
visible on the web, or alternatively copy it to somewhere to serve it
from.

View File

@@ -1,56 +0,0 @@
version: '2.2'
services:
coriolis_prod:
image: edcd/coriolis:master
build:
dockerfile: Dockerfile
args:
branch: master
restart: always
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
networks:
- web
labels:
- "traefik.docker.network=web"
- "traefik.enable=true"
- "traefik.basic.frontend.rule=Host:coriolis.io,coriolis.edcd.io"
- "traefik.basic.port=80"
- "traefik.basic.protocol=http"
coriolis_dev:
image: edcd/coriolis:develop
build:
dockerfile: Dockerfile
args:
branch: develop
restart: always
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
networks:
- web
labels:
- "traefik.docker.network=web"
- "traefik.enable=true"
- "traefik.basic.frontend.rule=Host:beta.coriolis.io,beta.coriolis.edcd.io"
- "traefik.basic.port=80"
- "traefik.basic.protocol=http"
coriolis_dw2:
image: edcd/coriolis:dw2
restart: always
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
networks:
- web
labels:
- "traefik.docker.network=web"
- "traefik.enable=true"
- "traefik.basic.frontend.rule=Host:dw2.coriolis.io"
- "traefik.basic.port=80"
- "traefik.basic.protocol=http"
networks:
web:
external: true

View File

@@ -1,96 +0,0 @@
worker_processes 1;
user nobody nobody;
error_log /tmp/error.log;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
client_body_temp_path /tmp/client_body;
fastcgi_temp_path /tmp/fastcgi_temp;
proxy_temp_path /tmp/proxy_temp;
scgi_temp_path /tmp/scgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
access_log /tmp/access.log;
error_log /tmp/error.log;
# https://nginx.org/en/docs/http/ngx_http_gzip_module.html
# Enable gzip compression.
# Default: off
gzip off;
# Compression level (1-9).
# 5 is a perfect compromise between size and CPU usage, offering about
# 75% reduction for most ASCII files (almost identical to level 9).
# Default: 1
gzip_comp_level 5;
# Don't compress anything that's already small and unlikely to shrink much
# if at all (the default is 20 bytes, which is bad as that usually leads to
# larger files after gzipping).
# Default: 20
gzip_min_length 256;
# Compress data even for clients that are connecting to us via proxies,
# identified by the "Via" header (required for CloudFront).
# Default: off
gzip_proxied any;
# Tell proxies to cache both the gzipped and regular version of a resource
# whenever the client's Accept-Encoding capabilities header varies;
# Avoids the issue where a non-gzip capable client (which is extremely rare
# today) would display gibberish if their proxy gave them the gzipped version.
# Default: off
gzip_vary on;
# Compress all output labeled with one of the following MIME-types.
# text/html is always compressed by gzip module.
# Default: text/html
gzip_types *;
brotli on;
# brotli_static on;
brotli_types *;
# This should be turned on if you are going to have pre-compressed copies (.gz) of
# static files available. If not it should be left off as it will cause extra I/O
# for the check. It is best if you enable this in a location{} block for
# a specific directory, or on an individual server{} level.
# gzip_static on;
keepalive_timeout 3000;
server {
listen 80;
listen [::]:80;
index index.html;
server_name localhost;
root /usr/share/nginx/html;
autoindex on;
location ~* \.(?:manifest|appcache|html?|xml|json|css|js|map|jpg|jpeg|gif|png|ico|svg|eot|ttf|woff|woff2)$ {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
access_log off;
}
location /service-worker.js {
expires -1;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
access_log off;
}
location / {
try_files $uri $uri/ /index.html =404;
}
location /iframe.html {
try_files $uri $uri/ /iframe.html =404;
}
}
}

View File

@@ -376,7 +376,6 @@ export default class Coriolis extends React.Component {
*/
render() {
let currentMenu = this.state.currentMenu;
return <div style={{ minHeight: '100%' }} onClick={this._closeMenu}
className={this.state.noTouch ? 'no-touch' : null}
>
@@ -389,6 +388,7 @@ export default class Coriolis extends React.Component {
{this.state.modal}
{this.state.tooltip}
<footer>
<div className="right cap">
<a href="https://github.com/EDCD/coriolis" target="_blank" rel="noopener noreferrer"
title="Coriolis Github Project">{window.CORIOLIS_VERSION} - {window.CORIOLIS_DATE}</a>

View File

@@ -72,6 +72,7 @@ Router.go = function(path, state) {
gaTrack(path);
let ctx = new Context(path, state);
Router.dispatch(ctx);
if (!ctx.unhandled) {
if (isStandAlone()) {
Persist.setState(ctx);

View File

@@ -160,8 +160,8 @@ export default class CostSection extends TranslatedComponent {
<tr className='main'>
<th colSpan='2' className='sortable le' onClick={() => this._sortBy('m')}>
{translate('module')}
{shipDiscount ? <u className='cap optional-hide' style={{ marginLeft: '0.5em' }}>{`[${translate('ship')} -${formats.pct(shipDiscount)}]`}</u> : null}
{moduleDiscount ? <u className='cap optional-hide' style={{ marginLeft: '0.5em' }}>{`[${translate('modules')} -${formats.pct(moduleDiscount)}]`}</u> : null}
{shipDiscount ? <u className='cap optional-hide' style={{ marginLeft: '0.5em' }}>{`[${translate('ship')} ${formats.pct(-1 * shipDiscount)}]`}</u> : null}
{moduleDiscount ? <u className='cap optional-hide' style={{ marginLeft: '0.5em' }}>{`[${translate('modules')} ${formats.pct(-1 * moduleDiscount)}]`}</u> : null}
</th>
<th className='sortable le' onClick={() => this._sortBy('cr')} >{translate('credits')}</th>
</tr>

View File

@@ -8,7 +8,6 @@ import cn from 'classnames';
import { Cogs, CoriolisLogo, Hammer, Help, Rocket, StatsBars } from './SvgIcons';
import Persist from '../stores/Persist';
import { toDetailedExport } from '../shipyard/Serializer';
import ModalBatchOrbis from './ModalBatchOrbis';
import ModalDeleteAll from './ModalDeleteAll';
import ModalExport from './ModalExport';
import ModalHelp from './ModalHelp';
@@ -367,7 +366,10 @@ export default class Header extends TranslatedComponent {
if (this.props.announcements) {
announcements = [];
for (let announce of this.props.announcements) {
announcements.push(<Announcement text={announce.message} />);
if (announce.expiry < Date.now()) {
continue;
}
announcements.push(<Announcement text={announce.text} />);
announcements.push(<hr/>);
}
}

View File

@@ -1,92 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import request from 'superagent';
import TranslatedComponent from './TranslatedComponent';
import { orbisUpload } from '../utils/ShortenUrl';
import Persist from '../stores/Persist';
/**
* Permalink modal
*/
export default class ModalBatchOrbis extends TranslatedComponent {
static propTypes = {
ships: PropTypes.any.isRequired
};
/**
* Constructor
* @param {Object} props React Component properties
*/
constructor(props) {
super(props);
this.state = {
orbisCreds: Persist.getOrbisCreds(),
resp: ''
};
}
/**
* Send ship to Orbis.zone
* @param {SyntheticEvent} e React Event
* @return {Promise} Promise sending post request to orbis
*/
sendToOrbis(e) {
let agent;
try {
agent = request.agent(); // apparently this crashes somehow
} catch (e) {
console.error(e);
}
if (!agent) {
agent = request;
}
const API_ORBIS = 'https://orbis.zone/api/builds/add/batch';
return new Promise((resolve, reject) => {
try {
agent
.post(API_ORBIS)
.withCredentials()
.redirects(0)
.set('Content-Type', 'application/json')
.send(this.props.ships)
.end((err, response) => {
console.log(response);
if (err) {
console.error(err);
this.setState({ resp: response.text });
reject('Bad Request');
} else {
this.setState({ resp: 'All builds uploaded. Check https://orbis.zone' });
resolve('All builds uploaded. Check https://orbis.zone');
}
});
} catch (e) {
console.log(e);
reject(e.message ? e.message : e);
}
});
}
/**
* Render the modal
* @return {React.Component} Modal Content
*/
render() {
let translate = this.context.language.translate;
this.sendToOrbis = this.sendToOrbis.bind(this);
return <div className='modal' onClick={ (e) => e.stopPropagation() }>
<h2>{translate('permalink')}</h2>
<br/>
<a className='button' href="https://orbis.zone/api/auth">Log in / signup to Orbis</a>
<br/><br/>
<h3 >{translate('success')}</h3>
<input value={this.state.resp} readOnly size={25} onFocus={ (e) => e.target.select() }/>
<br/><br/>
<p>Orbis.zone is currently in a trial period, and may be wiped at any time as development progresses. Some elements are also still placeholders.</p>
<button className={'l cb dismiss cap'} disabled={!!this.state.failed} onClick={this.sendToOrbis}>{translate('PHASE_UPLOAD_ORBIS')}</button>
<button className={'r dismiss cap'} onClick={this.context.hideModal}>{translate('close')}</button>
</div>;
}
}

View File

@@ -18,6 +18,7 @@ const STATE = {
*/
export default class ModalImport extends TranslatedComponent {
static propTypes = {
importString: PropTypes.string, // Optional: Default data for import modal
builds: PropTypes.object, // Optional: Import object
};
@@ -35,6 +36,30 @@ export default class ModalImport extends TranslatedComponent {
};
}
/**
* Import SLEF formatted builds. Sets state to a map of the builds on success
* and flags if there was only a single build.
*
* @param {string} importData - Array of the list of builds.
* @throws {string} If parse / import fails
*/
_importSlefBuilds(importData) {
const builds = importData.reduce((memo, { data }) => {
const shipModel = shipModelFromJson(data);
const ship = shipFromLoadoutJSON(data);
const shipTemplate = Ships[shipModel];
const shipName = data.ShipName || shipTemplate.properties.name;
const key = `Imported ${shipName}`;
memo[shipModel] = {};
memo[shipModel][key] = ship.toString();
return memo;
}, {});
this.setState({ builds, singleBuild: Object.keys(builds).length === 1 });
}
/**
* Validate the import string / text box contents
* @param {SyntheticEvent} event Event

View File

@@ -1,140 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import TranslatedComponent from './TranslatedComponent';
import { orbisUpload } from '../utils/ShortenUrl';
import Persist from '../stores/Persist';
/**
* Permalink modal
*/
export default class ModalOrbis extends TranslatedComponent {
static propTypes = {
ship: PropTypes.any.isRequired
};
/**
* Constructor
* @param {Object} props React Component properties
*/
constructor(props) {
super(props);
this.state = {
orbisCreds: Persist.getOrbisCreds(),
orbisUrl: '...',
ship: this.props.ship,
authenticatedStatus: 'Checking...'
};
this.orbisCategory = this.orbisCategory.bind(this);
}
/**
* Send ship to Orbis.zone
* @param {SyntheticEvent} e React Event
*/
sendToOrbis(e) {
const target = e.target;
target.disabled = true;
this.setState({ orbisUrl: 'Sending...' }, () => {
orbisUpload(this.props.ship, this.state.orbisCreds)
.then(orbisUrl => {
target.disabled = false;
this.setState({ orbisUrl });
})
.catch(err => {
target.disabled = false;
this.setState({ orbisUrl: 'Error - ' + err });
});
});
}
/**
* Get Orbis.zone auth status
* @returns {Object} auth status
*/
getOrbisAuthStatus() {
return fetch('https://orbis.zone/api/checkauth', {
credentials: 'include',
mode: 'cors'
})
.then(data => data.json())
.then(res => {
this.setState({ authenticatedStatus: res.status || res.error });
})
.catch(err => {
console.error(err);
this.setState({ authenticatedStatus: err.message });
});
}
/**
* Handler for changing cmdr name
* @param {SyntheticEvent} e React Event
*/
orbisPasswordHandler(e) {
let password = e.target.value;
this.setState({ orbisCreds: { email: this.state.orbisCreds.email, password } }, () => {
Persist.setOrbisCreds(this.state.orbisCreds);
});
}
/**
* Handler for changing cmdr name
* @param {SyntheticEvent} e React Event
*/
orbisUsername(e) {
let orbisUsername = e.target.value;
this.setState({ orbisCreds: { email: orbisUsername, password: this.state.orbisCreds.password } }, () => {
Persist.setOrbisCreds(this.state.orbisCreds);
});
}
/**
* Handler for changing category
* @param {SyntheticEvent} e React Event
*/
orbisCategory(e) {
let ship = this.state.ship;
let cat = e.target.value;
ship.category = cat;
this.setState({ ship });
}
/**
* Render the modal
* @return {React.Component} Modal Content
*/
render() {
let translate = this.context.language.translate;
this.orbisPasswordHandler = this.orbisPasswordHandler.bind(this);
this.orbisUsername = this.orbisUsername.bind(this);
this.sendToOrbis = this.sendToOrbis.bind(this);
this.getOrbisAuthStatus();
return <div className='modal' onClick={ (e) => e.stopPropagation() }>
<h2>{translate('upload to orbis')}</h2>
<br/>
<label>Orbis auth status: </label>
<input value={this.state.authenticatedStatus} readOnly size={25} onFocus={ (e) => e.target.select() }/>
<br/><br/>
<a className='button' href="https://orbis.zone/api/auth">Log in / signup to Orbis</a>
<br/><br/>
<h3>Category</h3>
<select onChange={this.orbisCategory}>
<option value="">No Category</option>
<option>Combat</option>
<option>Mining</option>
<option>Trading</option>
<option>Exploration</option>
<option>Passenger Liner</option>
<option>PvP</option>
</select>
<br/><br/>
<h3 >{translate('Orbis link')}</h3>
<input value={this.state.orbisUrl} readOnly size={25} onFocus={ (e) => e.target.select() }/>
<br/><br/>
<p>Orbis.zone is currently in a trial period, and may be wiped at any time as development progresses. Some elements are also still placeholders.</p>
<button className={'l cb dismiss cap'} disabled={!!this.state.failed} onClick={this.sendToOrbis}>{translate('PHASE_UPLOAD_ORBIS')}</button>
<button className={'r dismiss cap'} onClick={this.context.hideModal}>{translate('close')}</button>
</div>;
}
}

View File

@@ -291,8 +291,8 @@ export default class Offence extends TranslatedComponent {
<tr className='main'>
<th rowSpan='2' className='sortable' onClick={sortOrder.bind(this, 'classRating')}>{translate('weapon')}</th>
<th colSpan='1'>{translate('overall')}</th>
<th colSpan='2'>{translate('opponent\'s shields')}</th>
<th colSpan='2'>{translate('opponent\'s armour')}</th>
<th colSpan='3'>{translate('opponent\'s shields')}</th>
<th colSpan='3'>{translate('opponent\'s armour')}</th>
</tr>
<tr>
<th className='lft sortable' onMouseOver={termtip.bind(null, 'TT_EFFECTIVE_SDPS_SHIELDS')}
@@ -359,6 +359,7 @@ export default class Offence extends TranslatedComponent {
</span>
</td>
<td></td>
<td></td>
</tr>
}
</tbody>

View File

@@ -133,7 +133,7 @@
"pv": "Planetenfahrzeug-Hangar",
"rf": "Raffinerie",
"rg": "Schienenkanone",
"rsl": "Steuerung Aufklärungsdrohne",
"rsl": "Steuerung Forschungsdrohne",
"s": "Sensoren",
"sb": "Schildverstärker",
"sc": "Himmelskörperscanner",
@@ -146,7 +146,7 @@
"ul": "Salvenlaser",
"ws": "FS-Sogwolkenscanner",
"rpl": "Steuerung Reparaturdrohne",
"rcpl": "Recon Limpet Controller",
"rcpl": "Steuerung Aufklärungsdrohne",
"hrd": "Hüllenhärte",
"pax": "Pass",
"axmc": "AX-Mehrfachgeschütz",
@@ -162,7 +162,7 @@
"life support": "Lebenserhaltung",
"power plant": "Kraftwerk",
"thrusters": "Antriebe",
"power distriubtor": "Energieverteiler",
"power distributor": "Energieverteiler",
"sensors": "Sensoren",
"bins": "Behältnisse",
"bays": "Slots",

View File

@@ -205,7 +205,7 @@
"internal protection": "Internal protection",
"external protection": "External protection",
"engagement range": "Engagement range",
"boost interval": "Boost intervall",
"boost interval": "Boost interval",
"total": "Total",
"ammo": "Ammunition maximum",
"boot": "Boot time",

View File

@@ -2,15 +2,15 @@ export const formats = {
decimal: ',',
thousands: '.',
grouping: [3],
currency: ['', ''],
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']
days: ['domingo', 'segunda', 'terça', 'quarta', 'quinta', 'sexta', 'sábado'],
shortDays: ['dom', 'seg', 'ter', 'qua', 'qui', 'sex', 'sab'],
months: ['janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro'],
shortMonths: ['jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul', 'ago', 'set', 'out', 'nov', 'dez']
};
export { default as terms } from './pt.json';

File diff suppressed because one or more lines are too long

View File

@@ -5,7 +5,7 @@
"PHRASE_EXPORT_DESC": "Детальный JSON-экспорт вашей сборки для использования в других местах и инструментах",
"PHRASE_FASTEST_RANGE": "Последовательные прыжки максимальной дальности",
"PHRASE_IMPORT": "Для импорта вставьте код в эту форму",
"PHRASE_LADEN": "Масса корабля с учётом топлива и грузов",
"PHRASE_LADEN": "Масса корабля с учетом топлива и грузов",
"PHRASE_NO_BUILDS": "Нечего сравнивать",
"PHRASE_NO_RETROCH": "Нет ранних версий сборки",
"PHRASE_SELECT_BUILDS": "Выберите конфигурацию для сравнения",
@@ -13,18 +13,21 @@
"PHRASE_SG_RECOVER": "Восстановление с 0% до 50% объема щита, учитывая полный аккумулятор СИС в начале",
"PHRASE_UNLADEN": "Масса корабля без учета топлива и грузов",
"PHRASE_UPDATE_RDY": "Доступна новая версия. Нажмите для обновления.",
"PHRASE_ENGAGEMENT_RANGE": "Дистанция между кораблём и целью",
"PHRASE_SELECT_BLUEPRINT": "Нажмите чтобы выбрать чертёж",
"PHRASE_ENGAGEMENT_RANGE": "Дистанция между кораблем и целью",
"PHRASE_SELECT_BLUEPRINT": "Нажмите чтобы выбрать чертеж",
"PHRASE_BLUEPRINT_WORST": "Худшие основные значения для чертежа",
"PHRASE_BLUEPRINT_FIFTY": "50% значения для чертежа",
"PHRASE_BLUEPRINT_SEVEN_FIVE": "75% значения для чертежа",
"PHRASE_BLUEPRINT_RANDOM": "Случайный выбор между худшими и лучшими значениями для этого чертежа",
"PHRASE_BLUEPRINT_BEST": "Лучшие основные значения для чертежа",
"PHRASE_BLUEPRINT_EXTREME": "Лучшие положительные и худшие отрицательные основные значения для чертежа",
"PHRASE_BLUEPRINT_RESET": "Убрать все изменения и чертёж",
"PHRASE_BLUEPRINT_RESET": "Сбросить все модификаторы и чертеж",
"PHRASE_SELECT_SPECIAL": "Нажмите, чтобы выбрать экспериментальный эффект",
"PHRASE_NO_SPECIAL": "Без экспериментального эффекта",
"PHRASE_SHOPPING_LIST": "Станции, что продают эту сборку",
"PHRASE_SHOPPING_MATS": "Материалы которые нужны для сборки",
"PHRASE_REFIT_SHOPPING_LIST": "Станции, что продают необходимые модули",
"PHRASE_TOTAL_EFFECTIVE_SHIELD": "Общий урон, что может быть нанесён в каждым типе, если используются все щитонакопители",
"PHRASE_TOTAL_EFFECTIVE_SHIELD": "Общий урон, что может быть нанесен в каждым типе, если используются все щитонакопители",
"PHRASE_TIME_TO_LOSE_SHIELDS": "Щиты продержатся",
"PHRASE_TIME_TO_RECOVER_SHIELDS": "Щиты восстановятся за",
"PHRASE_TIME_TO_RECHARGE_SHIELDS": "Щиты будут заряжены за",
@@ -34,51 +37,59 @@
"PHRASE_EFFECTIVE_ARMOUR": "Эффективная сила брони против разных типов урона",
"PHRASE_DAMAGE_TAKEN": "% общих повреждений полученных в разных типах урона",
"PHRASE_TIME_TO_LOSE_ARMOUR": "Броня продержится",
"PHRASE_MODULE_PROTECTION_EXTERNAL": "Защита гнёзд",
"PHRASE_MODULE_PROTECTION_EXTERNAL": "Защита гнезд",
"PHRASE_MODULE_PROTECTION_INTERNAL": "Защита всех остальных модулей",
"PHRASE_OVERALL_DAMAGE": "Разбивка источников устойчивого ДПС",
"PHRASE_SHIELD_DAMAGE": "Подробности источников поддерживаемого ДПС против щитов",
"PHRASE_ARMOUR_DAMAGE": "Подробности источников поддерживаемого ДПС против брони",
"PHRASE_TIME_TO_REMOVE_SHIELDS": "Снимет щиты за",
"TT_TIME_TO_REMOVE_SHIELDS": "Непрерывным огнём из всех орудий",
"PHRASE_MULTI_CREW_CAPACITOR_POINTS": "Щелкните правой кновкой мыши чтобы объединить в группу.",
"TT_TIME_TO_REMOVE_SHIELDS": "Непрерывным огнем из всех орудий",
"PHRASE_TIME_TO_REMOVE_ARMOUR": "Снимет броню за",
"TT_TIME_TO_REMOVE_ARMOUR": "Непрерывным огнём из всех орудий",
"PHRASE_TIME_TO_DRAIN_WEP": "Опустошит ОРУЖ за",
"TT_TIME_TO_DRAIN_WEP": "Время, за которое опустошится аккумулятор ОРУЖ при стрельбе из всех орудий",
"TT_TIME_TO_REMOVE_ARMOUR": "Непрерывным огнем из всех орудий",
"PHRASE_TIME_TO_DRAIN_WEP": "Опустошит ОРУ за",
"TT_TIME_TO_DRAIN_WEP": "Время, за которое опустошится аккумулятор ОРУ при стрельбе из всех орудий",
"TT_TIME_TO_LOSE_SHIELDS": "Против поддерживаемой стрельбы из всех орудий противника",
"TT_TIME_TO_LOSE_ARMOUR": "Против поддерживаемой стрельбы из всех орудий противника",
"TT_MODULE_ARMOUR": "Броня, защищающая модули от урона",
"TT_MODULE_PROTECTION_EXTERNAL": "Процент урона, перенаправленного от гнёзд на наборы для усиления модулей",
"TT_MODULE_PROTECTION_INTERNAL": "Процент урона, перенаправленного от модулей вне гнёзд на наборы для усиления модулей",
"TT_EFFECTIVE_SDPS_SHIELDS": "Реальный поддерживаемый ДПС пока аккумулятор ОРУЖ не пуст",
"TT_MODULE_PROTECTION_EXTERNAL": "Процент урона, перенаправленного от гнезд на наборы для усиления модулей",
"TT_MODULE_PROTECTION_INTERNAL": "Процент урона, перенаправленного от модулей вне гнезд на наборы для усиления модулей",
"TT_EFFECTIVE_SDPS_SHIELDS": "Реальный поддерживаемый ДПС пока аккумулятор ОРУ не пуст",
"TT_EFFECTIVENESS_SHIELDS": "Эффективность в сравнении с попаданием по цели с 0-сопротивляемостью без пунктов в СИС на 0 метрах",
"TT_EFFECTIVE_SDPS_ARMOUR": "Реальный поддерживаемый ДПС пока аккумулятор ОРУЖ не пуст",
"TT_EFFECTIVE_SDPS_ARMOUR": "Реальный поддерживаемый ДПС пока аккумулятор ОРУ не пуст",
"TT_EFFECTIVENESS_ARMOUR": "Эффективность в сравнении с попаданием по цели с 0-сопротивляемостью на 0 метрах",
"PHRASE_EFFECTIVE_SDPS_SHIELDS": "ПДПС против щитов",
"PHRASE_EFFECTIVE_SDPS_ARMOUR": "ПДПС против брони",
"TT_SUMMARY_SPEED": "С полным топливным баком и 4 пунктами в ДВИ",
"TT_SUMMARY_SPEED": "С полным топливным баком и 4 пунктами в ДВГ",
"TT_SUMMARY_SPEED_NONFUNCTIONAL": "Маневровые двигатели выключены или превышена максимальная масса с топливом и грузом",
"TT_SUMMARY_BOOST": "С полным топливным баком и 4 пунктами в ДВИ",
"TT_SUMMARY_BOOST": "С полным топливным баком и 4 пунктами в ДВГ",
"TT_SUMMARY_BOOST_INTERVAL": "Время заполнения с 4 пунктами в СИС",
"TT_SUMMARY_BOOST_NONFUNCTIONAL": "Распределитель питания не может обеспечить достаточно энергии для форсажа",
"TT_SUMMARY_SHIELDS": "Чистая сила щита, включая усилители",
"TT_SUMMARY_SHIELDS_SCB": "Прочность щита, включая бустеры и SCB",
"TT_SUMMARY_SHIELDS_NONFUNCTIONAL": "Шитогенератор отсутствует или выключен",
"TT_SUMMARY_INTEGRITY": "Целостность корабля, включая переборки и наборы для усиления корпуса",
"TT_SUMMARY_HULL_MASS": "Масса корпуса без каких-либо модулей",
"TT_SUMMARY_UNLADEN_MASS": "Масса корпуса и модулей без топлива и груза",
"TT_SUMMARY_LADEN_MASS": "Масса корпуса и модулей с топливом и грузом",
"TT_SUMMARY_DPS": "Урон в секунду при стрельбе из всех орудий",
"TT_SUMMARY_EPS": "Расход аккумулятора ОРУЖ в секунду при стрельбе из всех орудий",
"TT_SUMMARY_TTD": "Время расхода аккумулятора ОРУЖ при стрельбе из всех орудий и с 4 пунктами в ОРУЖ",
"TT_SUMMARY_EPS": "Расход аккумулятора ОРУ в секунду при стрельбе из всех орудий",
"TT_SUMMARY_TTD": "Время расхода аккумулятора ОРУ при стрельбе из всех орудий и с 4 пунктами в ОРУ",
"TT_SUMMARY_MAX_SINGLE_JUMP": "Самый дальний возможный прыжок без груза и с топливом, достаточным только на сам прыжок",
"TT_SUMMARY_UNLADEN_SINGLE_JUMP": "Самый дальний возможный прыжок без груза и с полным топливным баком",
"TT_SUMMARY_LADEN_SINGLE_JUMP": "Самый дальний возможный прыжок с полным грузовым отсеком и с полным топливным баком",
"TT_SUMMARY_UNLADEN_TOTAL_JUMP": "Самая дальняя общая дистанция без груза, с полным топливным баком и при прыжках на максимальное расстояние",
"TT_SUMMARY_LADEN_TOTAL_JUMP": "Самая дальняя общая дистанция с полным грузовым отсеком, с полным топливным баком и при прыжках на максимальное расстояние",
"HELP_MODIFICATIONS_MENU": "Нажмите на номер, чтобы ввести новое значение, или потяните вдоль полосы для малых изменений",
"PHRASE_FAIL_EDENGINEER": "Не удалось отправить в EDEngineer (запустите EDEngineer и убедитесь, что API запущен, затем обновите страницу).",
"PHRASE_FIREFOX_EDENGINEER": "Отправка в EDEngineer несовместима с настройками безопасности Firefox. Пожалуйста, попробуйте еще раз в Google Chrome.",
"am": "Блок Автом. Полевого Ремонта",
"bh": "Переборки",
"bl": "Пучковый лазер",
"bsg": "Двухпоточный щитогенератор",
"c": "Орудие",
"c": "Пушка",
"causres": "Каустическое сопротивление",
"Caustic resistance": "Каустическое сопротивление",
"cc": "Контроллер магнитного снаряда для сбора",
"ch": "Разбрасыватель дипольных отражателей",
"cr": "Грузовой стеллаж",
@@ -98,14 +109,17 @@
"kw": "Сканер преступников",
"ls": "Система жизнеобеспечения",
"mc": "Многоствольное орудие",
"axmc": "Многоствольное орудие АИ",
"ml": "Проходочный лазер",
"mr": "Ракетный лоток",
"axmr": "Блок ракет АИ",
"mrp": "Набор для усиления модуля",
"nl": "Мины",
"pa": "Ускоритель плазмы",
"pas": "Комплект для сближения с планетой",
"pc": "Контроллер магнитного снаряда для геологоразведки",
"pce": "Каюта пассажира эконом-класса",
"passenger capacity": "Количество пассажиров",
"pci": "Каюта пассажира бизнес-класса",
"pcm": "Каюта пассажира первого класса",
"pcq": "Каюта пассажира класса люкс",
@@ -113,33 +127,63 @@
"pl": "Импульсный лазер",
"po": "Точечная оборона",
"pp": "Силовая установка",
"gpp": "Силовая установка Стражей",
"gpd": "Гибридный распределитель питания Стражей",
"gpc": "Плазменная пушка Стражей",
"ggc": "Пушка Гаусса Стражей",
"gsrp": "Набор для усиления щита Стражей",
"gfsb": "Ускоритель FSD Стражей",
"ghrp": "Набор для усиления корпуса Стражей",
"gmrp": "Набор для усиления модуля Стражей",
"pwa": "Анализатор импульсных волн",
"abl": "Абразивный бластер",
"scl": "Пусковая установка для сейсмических снарядов",
"sdm": "Вытесняющая ракета для добычи глубинных залежей",
"tbsc": "Шоковое орудие",
"gsc": "Осколочное орудие Стражей",
"psg": "Призматический щитогенератор",
"pv": "Гараж для планетарного транспорта",
"rf": "Устройство переработки",
"rfl": "Зенитная установка (снаряды с дистанционным подрывом)",
"rg": "Электромагнитная пушка",
"rsl": "Дроны-исследователи",
"s": "Сенсоры",
"sb": "Усилитель щита",
"sc": "Сканер обнаружения",
"scb": "Щитонакопитель",
"sfn": "Нейтрализатор глушащего поля",
"sg": "Щитогенератор",
"ss": "Сканер поверхностей",
"sua": "Помощь в гиперкрейсерском режиме",
"t": "Маневровые двигатели",
"tp": "Торпедная стойка",
"ul": "Пульсирующие лазеры",
"Send To EDEngineer": "Отправить в EDEngineer",
"ws": "Сканер следа FSD",
"rpl": "Дроны-ремонтники",
"rcpl": "Дроны-разведчики",
"xs": "Сканер «инопланетянин»",
"tbem": "Блок энзимных ракет",
"tbrfl": "Установка для стрельбы стреловидными снарядами с дистанционным подрывом",
"dtl": "Дроны-очистители",
"mahr": "Набор для усиления корпуса из Метасплава",
"emptyrestricted": "пусто (ограниченно)",
"damage dealt to": "Урон нанесён",
"damage dealt to": "Урон нанесен",
"damage received from": "Урон получен от",
"against shields": "Против щитов",
"against hull": "Против корпуса",
"total effective shield": "Общие эффективные щиты",
"ammunition": "Припасы",
"secs": "с",
"rebuildsperbay": "Построек за полосу",
"bays": "Ячейки",
"rebuildsperbay": "Истребителей в ячейке",
"mroll": "Roll",
"feature": "Свойство",
"worst": "Худшее",
"average": "Среднее",
"random": "Случайное",
"best": "Лучшее",
"current": "Текущее",
"extreme": "Экстремальное",
"reset": "Сброс",
"dpe": "Урон на МДж энергии",
@@ -148,6 +192,8 @@
"dpssdps": "Урон в секунду (поддерживаемый урон в секунду)",
"eps": "Энергия в секунду",
"epsseps": "Энергия в секунду (поддерживаемая энергия в секунду)",
"fallofffromrange": "Спад",
"falloff": "Спад",
"hps": "Нагрев в секунду",
"hpsshps": "Нагрев в секунду (поддерживаемый нагрев в секунду)",
"damage by": "Урон",
@@ -164,13 +210,15 @@
"internal protection": "Внутренняя защита",
"external protection": "Внешняя защита",
"engagement range": "Боевое расстояние",
"boost interval": "Интервал повыш.",
"total": "Всего",
"ammo": "Боекомплект",
"ammo": "Макс. боекомплект",
"boot": "Время загрузки",
"hacktime": "Время взлома",
"brokenregen": "Скорость восстановления при пробое",
"burst": "Длина очереди",
"burstrof": "Скорострельность очереди",
"clip": "Боекомплект",
"clip": "Размер боекомплекта",
"damage": "Урон",
"distdraw": "Тяга распределителя",
"duration": "Продолжительность",
@@ -199,11 +247,16 @@
"rof": "Скорострельность",
"angle": "Угол сканера",
"scanrate": "Скорость сканера",
"proberadius": "Радиус зонда",
"scantime": "Время сканирования",
"scan range": "Дальность",
"max angle": "Макс. угол",
"shield": "Щит",
"armour": "Броня",
"shieldboost": "Усиление щитов",
"shieldreinforcement": "Усилитель щита",
"shotspeed": "Скорость выстрела",
"shotdmg": "Урон за выстрел(DPS)",
"spinup": "Время раскрутки",
"syscap": "Ресурс систем",
"sysrate": "Перезарядка систем",
@@ -234,9 +287,12 @@
"explosive": "Взрывч.",
"kinetic": "Механич.",
"thermal": "Тепл.",
"caustic": "Каустич.",
"generator": "Генератор",
"boosters": "Усилители",
"cells": "Ячейки",
"shield addition": "ДОбавления к щиту",
"jump addition": "ДОбавления к прыжку",
"bulkheads": "Переборки",
"reinforcement": "Усилители",
"power and costs": "Энергия и стоимость",
@@ -250,7 +306,7 @@
"damage to opponent's shields": "Урон щиту противника",
"damage to opponent's hull": "Урон корпусу противника",
"offence": "Нападение",
"defence": "Оборона",
"defence": "Защита",
"shield metrics": "Данные щита",
"raw shield strength": "Чистая мощность щита",
"shield sources": "Ресурсы щита",
@@ -265,28 +321,70 @@
"defence metrics": "Данные обороны",
"fuel carried": "Топливо на борту",
"cargo carried": "Груз на борту",
"ship control": "Управление кораблём",
"ship control": "Управление кораблем",
"opponent": "Противник",
"opponent's shields": "Щит противника",
"opponent's armour": "Броня противника",
"overall damage": "общий урон",
"overall": "общий",
"shield damage sources": "источники урона по щиту",
"armour damage sources": "источники урона по броне",
"never": "Никогда",
"stock": "базовый",
"boost": "форсаж",
"tab_defence": "защита",
"federation rank 1": "Рекрут",
"federation rank 2": "Кадет",
"federation rank 3": "Гардемарин",
"federation rank 4": "Старшина",
"federation rank 5": "Главный старшина",
"federation rank 6": "Уорент-офицер",
"federation rank 7": "Энсин",
"federation rank 8": "Лейтенант",
"federation rank 9": "Капитан-лейтенант",
"federation rank 10": "Начальник гарнизона",
"federation rank 11": "Командир корабля",
"federation rank 12": "Контр-адмирал",
"federation rank 13": "Вице-адмирал",
"federation rank 14": "Адмирал",
"federation rank required": "Минимальный ранг федерации для покупки",
"empire rank 1": "Чужак",
"empire rank 2": "Крепостной",
"empire rank 3": "Мастер",
"empire rank 4": "Оруженосец",
"empire rank 5": "Рыцарь",
"empire rank 6": "Лорд",
"empire rank 7": "Барон",
"empire rank 8": "Виконт",
"empire rank 9": "Граф",
"empire rank 10": "Эрл",
"empire rank 11": "Маркиз",
"empire rank 12": "Герцог",
"empire rank 13": "Принц",
"empire rank 14": "Король",
"empire rank required": "Минимальный ранг империи для покупки",
"kg": "кг",
"kg/s": "кг/с",
"km": "км",
"m": "м",
"MJ": "МДж",
"MW": "МВт",
"T": "т",
"°/s": "°/с",
"/s": "/с",
"/min": "/мин",
"m/s": "м/с",
"Ls": "Св.сек",
"LY": "Св.лет",
"CR": "кр.",
"S": "M",
"S": "М",
"M": "С",
"L": "б",
"H": "O",
"U": "B",
"L": "Б",
"H": "О",
"U": "В",
"small": "Малый",
"medium": "Средний",
"large": "большой",
"large": "Большой",
"alpha": "Альфа",
"beta": "Бета",
"standard": "Стандартный",
@@ -304,23 +402,24 @@
"full tank": "Полный бак",
"internal compartments": "внутренние отсеки",
"jump range": "Дальность прыжка",
"mass lock factor": "Масс. блок",
"mass lock factor": "Коэффициент гравитационного захвата",
"max mass": "Максимальная масса",
"minimum mass": "Минимальная масса",
"optimal mass": "Оптимальная масса",
"net cost": "разница в цене",
"none created": "не создано",
"refuel time": "Время дозаправки",
"retrofit from": "модификация от",
"T-Load": "Тепл.",
"utility mounts": "Вспомогательное оборудование",
"about": "О ...",
"about": "О сайте",
"action": "Действие",
"added": "Добавлено",
"armour": "Броня",
"available": "доступно",
"backup": "Резервная копия",
"bins": "контейнеры",
"build": "cборка",
"builds": "cборки",
"build": "сборка",
"builds": "сборки",
"buy": "купить",
"cancel": "отменить",
"cargo": "Груз",
@@ -339,16 +438,16 @@
"DPS": "УВС",
"efficiency": "Эффективность",
"empty": "пусто",
"ENG": "ДВИ",
"ENG": "ДВГ",
"export": "Экспорт",
"forum": "Форум",
"fuel": "Топливо",
"fuel": "Топл.",
"hardpoints": "Орудийные порты",
"hull": "Корпус",
"import": "импортировать ",
"insurance": "Страховка",
"jumps": "Прыжков",
"laden": "Груженый",
"laden": "Груж",
"language": "Язык",
"maneuverability": "Маневренность",
"max": "Макс",
@@ -361,13 +460,15 @@
"rate": "скорость",
"rename": "Переименовать",
"repair": "Починка",
"ret": "Убр.",
"ret": "Убр",
"retracted": "Убрано",
"ROF": "В/сек",
"ROF": "В\/сек",
"save": "Сохранить",
"sell": "Продать",
"settings": "Настройки",
"shields": "Щиты",
"No Shield": "Нет щита",
"Never": "Никогда",
"ship": "Корабль",
"ships": "Корабли",
"shortened": "Укороченный",
@@ -377,8 +478,296 @@
"SYS": "СИС",
"time": "Время",
"type": "Тип",
"unladen": "Пустой",
"unladen": "Пуст",
"URL": "Ссылка",
"WEP": "ОРУЖ",
"yes": "Да"
"WEP": "ОРУ",
"yes": "Да",
"crew": "экипаж",
"jump": "прыж",
"pax": "псж",
"RST": "СБР",
"grade": "уровень",
"total laden": "всего груж",
"total unladen": "всего пуст",
"module": "модуль",
"announcements": "объявления",
"resistance": "сопротивление",
"Lightweight Alloy": "Легкие сплавы",
"base": "базовые",
"core module classes": "основные модули",
"Group highlighted ships": "Сгруппировать выделенные корабли",
"tooltips": "всплывающие подсказки",
"module resistances": "сопротивление модулей",
"power plant": "силовая установка",
"thrusters": "маневровые двигатели",
"frame shift drive": "рамочно-сместительный двигатель",
"life support": "система жизнеобеспечения",
"power distributor": "распределитель питания",
"sensors": "сенсоры",
"fuel tank": "топливный бак",
"resting heat (Beta)": "тепло покоя (бета)",
"hull hardness": "Прочность корпуса",
"weapon": "оружие",
"maximum speed": "максимальная скорость",
"maximum range": "максимальная дальность",
"shortlink": "короткая ссылка",
"guardian": "стражи",
"engineers": "инженеры",
"component": "компонент",
"amount": "кол-во",
"core internal": "основное оборуднование",
"optional internal": "доп. оборудование",
"Heat Sink Launcher": "Теплоотводная катапульта",
"scanners": "сканеры",
"experimental": "экспериментальное",
"mining": "шахтерство",
"lasers": "лазеры",
"ordnance": "артиллерия",
"projectiles": "с боеприпасами",
"hangars": "ангары",
"limpet controllers": "контроллеры снарядов",
"passenger cabins": "каюты пассажиров",
"structural reinforcement": "структурные усиления",
"flight assists": "помощники в полете",
"modifications": "модификации",
"wep_reload": "перезарядка",
"optimal multiplier": "оптимальный усилитель",
"Cargo Hatch": "Грузовой люк",
"Chaff Launcher": "Разбрасыватель дипольных отражателей",
"Point Defence": "Точечная оборона",
"Electronic Countermeasure": "Электронное противодействие",
"Xeno Scanner": "Сканер «инопланетянин»",
"Shutdown Field Neutraliser": "Нейтрализатор глушащего поля",
"Disruptor": "Диверсант",
"Pacifier": "Миротворец",
"Advanced Plasma Accelerator": "Улучшенный ускоритель плазмы",
"Cytoscrambler": "Дезинтегратор",
"Retributor": "Каратель",
"Enforcer": "Убийца",
"Imperial Hammer": "Имперский молот",
"Rocket Propelled FSD Disruptor": "Ракетный FSD-разрушитель",
"Pack-Hound": "Гончие",
"Shock Mine Launcher": "Установщик шоковых мин",
"Mining Lance": "Копье шахтера",
"Corrosion Resistant": "Коррозийно-устойчивый стеллаж",
"Standard Docking Computer": "Стандартный стыковочный компьютер",
"Advanced Docking Computer": "Улучшенный стыковочный компьютер",
"Detailed Surface Scanner": "Подробный сканер поверхности",
"Supercruise Assist": "Помощь в гиперкрейсерском режиме",
"Guardian Power Distributor": "Рапределитель питания Стражей",
"Enhanced Performance": "Усиленные маневровые двигатели",
"Guardian Hybrid Power Plant": "Гибридная силовая установка Стражей",
"Reinforced Alloy": "Укрепленные сплавы",
"Military Grade Composite": "Композит военного класса",
"Mirrored Surface Composite": "Композит с зеркальной поверхностью",
"Reactive Surface Composite": "Композит с реактивной поверхностью",
"Proto Light Alloys": "Опытные легкие сплавы",
"Ammo capacity": "Вместимость магазина",
"Lightweight": "Облегченный",
"Reinforced": "Усиленный",
"Shielded": "Защищенный",
"Fast scan": "Быстрое сканирование",
"Long range": "Дальнего действия",
"Wide angle": "Широкоугольный",
"Blast resistant": "Взрывостойкий",
"Heavy duty": "Надежный",
"Kinetic resistant": "Противокинетический",
"Resistance augmented": "С универсальной защитой",
"Thermal resistant": "Термостойкий",
"Thermo Block": "Блокировка тепла",
"Force Block": "Усиленная блокировка",
"Blast Block": "Блокировка взрыва",
"Flow Control": "Контроль интенсивности",
"Double Braced": "Двойная прочность",
"Super Capacitors": "Суперконденсаторы",
"Efficient": "Эффективный",
"Focused": "Точный",
"Overcharged": "Усиленный",
"Rapid fire": "Скорострельный",
"Short range": "Ближнего действия",
"Sturdy": "Прочный",
"Oversized": "Сверхразмер",
"Stripped Down": "Урезанный вариант",
"Phasing sequence": "Последовательность фазирования",
"Concordant sequence": "Последовательность координации",
"Scramble spectrum": "Отключающая сетка",
"Thermal shock": "Тепловой удар",
"Emissive munitions": "Эмиссионные припасы",
"Multi-servos": "Сервосистема",
"Inertial impact": "Инерционный удар",
"Thermal vent": "Теплоотдача",
"Regeneration sequence": "Последовательность восстановления",
"Thermal conduit": "Проводник тепла",
"High capacity": "Вместительный магазин",
"Incendiary rounds": "Зажигательные припасы",
"Auto loader": "Автоматическая система заряжения",
"Smart rounds": "Умные боеприпасы",
"Corrosive shell": "Разъедающие припасы",
"Force shell": "Усиленные снаряды",
"High yield shell": "Снаряд большой мощности",
"Dispersal field": "Рассеивающее поле",
"Thermal cascade": "Термический залп",
"Double shot": "Двойной выстрел",
"Dazzle shell": "Ослепляющие снаряды",
"Screening shell": "Заслоняющие снаряды",
"Drag munitions": "Замедляющие боеприпасы",
"Target lock breaker": "Генератор помех для системы захвата цели",
"Plasma Slug": "Плазменный рельсовый снаряд",
"Feedback Cascade": "Ответный запл",
"Super Penetrator": "Модуль сверхпробития",
"Overload munitions": "Вызывающие перезагрузку боеприпасы",
"Penetrator payload": "Бронебойные снаряды",
"Penetrator Payload": "Бронебойные снаряды",
"FSD interrupt": "Помеха для FSD",
"Penetrator Munitions": "Бронебойные боеголовки",
"Mass lock munition": "Боеприпасы с гравитационным захватом",
"Mass Lock Munition": "Боеприпасы с гравитационным захватом",
"Reverberating cascade": "Отраженный залп",
"Shift-lock canister": "Рамоблокирующая кассета",
"Ion disruptor": "Ионный дестабилизатор",
"Radiant Canister": "Светящаяся кассета",
"Expanded capture arc": "Расширенная дуга захвата",
"Enhanced low power": "Улучшенное энергосбережение",
"Fast Charge": "Быстрый заряд",
"Multi-weave": "Мультипрошивка",
"Hi-Cap": "Высокая ёмкость",
"Lo-draw": "Пониженное потребление",
"Rapid charge": "Быстрая зарядка",
"Specialised": "Адаптивный",
"Boss Cells": "Босс-ячейки",
"Recycling Cell": "Рециркуляционная ячейка",
"Reflective Plating": "Отражающая броня",
"Angled Plating": "Угловая броня",
"Layered Plating": "Многослойная броня",
"Deep Plating": "Утолщенная броня",
"Expanded Probe Scanning Radius": "Увеличение радиуса сканирования зондов",
"High charge capacity": "Высокоёмкий",
"Charge enhanced": "Быстрозаряжающийся",
"Engine focused": "Фокус на двигатель",
"System focused": "Фокус на систему",
"Weapon focused": "Фокус на орудия",
"Super Conduits": "Сверхпроводники",
"Cluster Capacitors": "Кассетные конденсаторы",
"Increased range": "Увеличенная дальность",
"Faster boot sequence": "Ускорение запуска",
"Deep Charge": "Заряд повышенной мощности",
"Thermal Spread": "Рассеивание тепла",
"Mass Manager": "Распределитель гравитации",
"Dirty": "«Грязная» донастройка",
"Clean": "«Чистая» донастройка",
"Drag Drives": "Ускорители",
"Drive Distributors": "Распределители тяги",
"Armoured": "Бронированный",
"Low emissions": "Малое излучение",
"Monstered": "Монстрация",
"roles": "роли",
"Maximize Jump Range": "Максимизировать дальность прыжка",
"Multi-purpose": "Многоцелевой",
"Combat": "Боец",
"Trader": "Торговец",
"Explorer": "Исследователь",
"Planetary Explorer": "Планетарный исследователь",
"Miner": "Шахтер",
"Racer": "Гонщик",
"Aberrant Shield Pattern Analysis": "Анализ аномального поведения щита",
"Abnormal Compact Emissions Data": "Аномальные компактные данные об излучении",
"Aerogel": "Аэрогель",
"Adaptive Encryptors Capture": "Захват адаптивного шифровальщика",
"Anomalous Bulk Scan Data": "Аномальный массив данных сканирования",
"Anomalous FSD Telemetry": "Аномальная телеметрия FSD",
"Antimony": "Сурьма",
"Arsenic": "Мышьяк",
"Atypical Disrupted Wake Echoes": "Атипичное эхо поврежденного следа",
"Atypical Encryption Archives": "Нетипичные архивы шифрования",
"Basic Conductors": "Простые проводники",
"Bio-Mechanical Conduits": "Биомеханические энергопроводники",
"Biotech Conductors": "Биотехнические проводники",
"Boron": "Бор",
"Cadmium": "Кадмий",
"Carbon": "Углерод",
"Carbon Fibre Plating": "Углеволоконная броня",
"Chemical Distillery": "Оборудование для перегонки химикатов",
"Chemical Manipulators": "Манипуляторы для работы с химикатами",
"Chemical Processors": "Оборудование для химобработки",
"Chromium": "Хром",
"Classified Scan Databanks": "Засекреченные базы данных сканированоя",
"Classified Scan Fragment": "Засекреченные фрагменты данных сканирования",
"Compound Shielding": "Многоступенчатая защита",
"Conductive Ceramics": "Проводящая керамика",
"Conductive Components": "Проводящие компоненты",
"Conductive Polymers": "Проводящие полимеры",
"Configurable Components": "Настраиваемые компоненты",
"Core Dynamics Composites": "Композиты Core Dynamics",
"Cracked Industrial Firmware": "Взломанные промышленные микропрограммы",
"Datamined Wake Exceptions": "Исключения из глубинного анализа данных следа",
"Decoded Emission Data": "Расшифрованные данные об излучении",
"Distorted Shield Cycle Recordings": "Поврежденные цикличные записи щита",
"Divergent Scan Data": "Неформатные данные сканирования",
"Eccentric Hyperspace Trajectories": "Аномальные траектории в гиперпространстве",
"Electrochemical Arrays": "Электрохимические массивы",
"Exceptional Scrambled Emission Data": "Исключительные зашифрованные данные об излучении",
"Exquisite Focus Crystals": "Отборные фокусировочные кристаллы",
"Flawed Focus Crystals": "Поврежденные фокусировочные кристаллы",
"Focus Crystals": "Фокусировочные кристаллы",
"Galvanising Alloys": "Сплавы для гальванизации",
"Germanium": "Германий",
"Grid Resistors": "Наборные резисторы",
"Heat Conduction Wiring": "Теплопроводящие провода",
"Heat Dispersion Plate": "Теплорассеивающая пластина",
"Heat Exchangers": "Теплообменные агрегаты",
"Heat Vanes": "Тепловые заслонки",
"High Density Composites": "Высокоплотные композиты",
"Hybrid Capacitors": "Гибридные конденсаторы",
"Imperial Shielding": "Имперская защита",
"Improvised Components": "Кустарные компоненты",
"Inconsistent Shield Soak Analysis": "Неполный анализ поглощения щита",
"Iron": "Железо",
"Irregular Emission Data": "Нестандартные данные об излучении",
"Manganese": "Марганец",
"Mechanical Components": "Механические компоненты",
"Mechanical Equipment": "Механическое оборудование",
"Mechanical Scrap": "Механические отходы",
"Mercury": "Ртуть",
"Military Grade Alloys": "Сплавы военного назначения",
"Military Supercapacitors": "Военные суперконденсаторы",
"Modified Consumer Firmware": "Измененные пользовательские микропрограммы",
"Modified Embedded Firmware": "Измененные встроенные микропрограммы",
"Molybdenum": "Молибден",
"Nickel": "Никель",
"Niobium": "Ниобий",
"Open Symmetric Keys": "Открытые симметричные ключи",
"Pharmaceutical Isolators": "Фармацевтические изоляционные материалы",
"Phase Alloys": "Фазовые сплавы",
"Phosphorus": "Фосфор",
"Polymer Capacitors": "Полимерные конденсаторы",
"Precipitated Alloys": "Осажденные сплавы",
"Proprietary Composites": "Патентованные композиты",
"Proto Heat Radiators": "Прототипы теплоизлучателей",
"Proto Radiolic Alloys": "Сплавы для изготовления зондов",
"Refined Focus Crystals": "Обработанные фокусировочные кристаллы",
"Ruthenium": "Рутений",
"Salvaged Alloys": "Захваченные сплавы",
"Security Firmware Patch": "Обновление для защитной микропрограммы",
"Selenium": "Селениум",
"Shield Emitters": "Щитоизлучатели",
"Shielding Sensors": "Сенсоры системы экранирования",
"Specialised Legacy Firmware": "Специальные микропрограммы предыдущего поколения",
"Strange Wake Solutions": "Странные расчеты следа",
"Sulphur": "Сера",
"Tagged Encryption Codes": "Меченные шифровальные коды",
"Technetium": "Технеций",
"Tellurium": "Теллурий",
"Thermic Alloys": "Термические сплавы",
"Tin": "Олово",
"Tungsten": "Вольфрам",
"Unexpected Emission Data": "Неожиданные данные об излучении",
"Unidentified Scan Archives": "Неопознанные архивы сканирования",
"Untypical Shield Scans": "Нетипичные данные сканирования щитов",
"Unusual Encrypted Files": "Особые зашифрованные файлы",
"Vanadium": "Ванадий",
"Worn Shield Emitters": "Изношенные щитоизлучатели",
"Yttrium": "Иттрий",
"Zinc": "Цинк",
"Zirconium": "Цирконий"
}

View File

@@ -94,39 +94,6 @@ export default class AboutPage extends Page {
</a>
.
</p>
<h3>Supporting Coriolis</h3>
<p>
Coriolis is an open source project, and I work on it in my free time.
I have set up a patreon at{' '}
<a href="https://www.patreon.com/coriolis_elite">
patreon.com/coriolis_elite
</a>
, which will be used to keep Coriolis up to date and the servers
running.
</p>
<form
action="https://www.paypal.com/cgi-bin/webscr"
method="post"
target="_top"
>
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id" value="SJBKT2SWEEU68" />
<input
type="image"
src="https://www.paypalobjects.com/en_AU/i/btn/btn_donate_SM.gif"
border="0"
name="submit"
alt="PayPal The safer, easier way to pay online!"
/>
<img
alt=""
border="0"
src="https://www.paypalobjects.com/en_AU/i/scr/pixel.gif"
width="1"
height="1"
/>
</form>
</div>
);
}

View File

@@ -16,7 +16,6 @@ import {
LinkIcon,
ShoppingIcon,
MatIcon,
OrbisIcon
} from '../components/SvgIcons';
import ShipSummaryTable from '../components/ShipSummaryTable';
import StandardSlotSection from '../components/StandardSlotSection';
@@ -26,7 +25,6 @@ import UtilitySlotSection from '../components/UtilitySlotSection';
import OutfittingSubpages from '../components/OutfittingSubpages';
import ModalExport from '../components/ModalExport';
import ModalPermalink from '../components/ModalPermalink';
import ModalOrbis from '../components/ModalOrbis';
import autoBind from 'auto-bind';
import { assign } from 'lodash';
import EDEngineerButton from '../components/EDEngineerButton';
@@ -358,23 +356,6 @@ export default class OutfittingPage extends Page {
this.context.showModal(<ModalPermalink url={window.location.href} />);
}
/**
* Generate Orbis link
*/
_genOrbis() {
const data = {};
const ship = this.state.ship;
ship.coriolisId = ship.id;
data.coriolisShip = ship;
data.url = window.location.href;
data.title = this.state.buildName || ship.id;
data.description = this.state.buildName || ship.id;
data.ShipName = ship.id;
data.Ship = ship.id;
console.log(data);
this.context.showModal(<ModalOrbis ship={data} />);
}
/**
* Open up a window for EDDB with a shopping list of our components
*/
@@ -579,13 +560,6 @@ export default class OutfittingPage extends Page {
>
<LinkIcon className="lg" />
</button>
<button
onClick={this._genOrbis}
onMouseOver={termtip.bind(null, 'PHASE_UPLOAD_ORBIS')}
onMouseOut={hide}
>
<OrbisIcon className="lg" />
</button>
<EDEngineerButton ship={ship} />
</div>
</div>

View File

@@ -61,6 +61,14 @@ export default class Page extends React.Component {
*/
componentDidMount() {
document.title = this.state.title || 'Coriolis';
try {
(window.adsbygoogle = window.adsbygoogle || []).push({
google_ad_client: "ca-pub-3709458261881414",
enable_page_level_ads: true
});
} catch (error) {
}
}
/**

View File

@@ -13,7 +13,6 @@ const LS_KEY_STATE = 'state';
const LS_KEY_SIZE_RATIO = 'sizeRatio';
const LS_KEY_TOOLTIPS = 'tooltips';
const LS_KEY_ROLLS = 'matsPerGrade';
const LS_KEY_ORBIS = 'orbis';
let LS;
@@ -91,7 +90,6 @@ export class Persist extends EventEmitter {
let moduleDiscount = _get(LS_KEY_MOD_DISCOUNT);
let buildJson = _get(LS_KEY_BUILDS);
this.orbisCreds = _get(LS_KEY_ORBIS) || { email: '', password: '' };
this.onStorageChange = this.onStorageChange.bind(this);
this.langCode = _getString(LS_KEY_LANG) || 'en';
this.insurance = insurance && Insurance[insurance.toLowerCase()] !== undefined ? insurance : 'standard';
@@ -155,10 +153,6 @@ export class Persist extends EventEmitter {
this.matsPerGrade = JSON.parse(newValue);
this.emit('matsPerGrade', this.matsPerGrade);
break;
case LS_KEY_ORBIS:
this.orbisCreds = JSON.parse(newValue);
this.emit('orbis', this.orbisCreds);
break;
}
} catch (e) {
// On JSON.Parse Error - don't sync or do anything
@@ -184,24 +178,6 @@ export class Persist extends EventEmitter {
this.emit('language', langCode);
}
/**
* Get the current orbis.zone credentials
* @return {String} language code
*/
getOrbisCreds() {
return this.orbisCreds;
};
/**
* Update and save the orbis.zone credentials
* @param {Object} creds object with username and password properties.
*/
setOrbisCreds(creds) {
this.langCode = creds;
_put(LS_KEY_ORBIS, creds);
this.emit('orbis', creds);
}
/**
* Show tooltips setting
* @param {boolean} show Optional - update setting

View File

@@ -51,7 +51,7 @@ function orbisShorten(url, success, error) {
}
}
const API_ORBIS = 'https://orbis.zone/api/builds/add';
const API_ORBIS = 'https://api.orbis.zone/ships';
/**
* Upload to Orbis
* @param {object} ship The URL to shorten

View File

@@ -2,19 +2,14 @@
<html>
<head>
<title>Coriolis EDCD Edition</title>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script>
(adsbygoogle = window.adsbygoogle || []).push({
google_ad_client: "ca-pub-3709458261881414",
enable_page_level_ads: true
});
</script>
<meta charset="UTF-8">
<link rel="stylesheet" href="<%= htmlWebpackPlugin.files.css[0] %>">
<!-- Standard headers -->
<meta name="description" content="A ship builder, outfitting and comparison
tool for Elite Dangerous">
<meta name="mobile-web-app-capable" content="yes">
<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=0">
<link rel="manifest" href="/manifest.json">
@@ -32,7 +27,7 @@
<meta name="msapplication-TileImage" content="/mstile-144x144.png">
<meta name="msapplication-config" content="/browserconfig.xml">
<meta name="theme-color" content="#000000">
<!-- <script data-ad-client="ca-pub-3709458261881414" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> -->
<script>
window.CORIOLIS_GAPI_KEY = '<%- htmlWebpackPlugin.options.gapiKey %>';
window.CORIOLIS_VERSION = '<%- htmlWebpackPlugin.options.version %>';
@@ -59,7 +54,8 @@
</script>
</head>
<body style="background-color:#000;">
<section id="coriolis"></section>
<section id="coriolis">
</section>
</body>
</html>

104
src/migrate.html Normal file
View File

@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Coriolis EDCD Edition</title>
<meta charset="UTF-8" />
<link rel="stylesheet" href="<%= htmlWebpackPlugin.files.css[0] %>" />
<!-- Standard headers -->
<meta
name="description"
content="A ship builder, outfitting and comparison
tool for Elite Dangerous"
/>
<meta name="mobile-web-app-capable" content="yes" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=0"
/>
<link rel="manifest" href="/manifest.json" />
<link rel="shortcut icon" href=/favicon2.ico>
<link
rel="icon"
sizes="152x152 192x192"
type="image/png"
href="/192x192.png"
/>
<!-- Bugsnag -->
<script src="https://d2wy8f7a9ursnm.cloudfront.net/v5.0.0/bugsnag.min.js"></script>
<script>
window.bugsnagClient = bugsnag('ba9fae819372850fb660755341fa6ef5', {appVersion: window.BUGSNAG_VERSION || undefined})
window.Bugsnag = window.bugsnagClient
</script>
<!-- Apple/iOS headers -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="Coriolis" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<!-- Microsoft Windows Phone/Tablet headers -->
<meta name="msapplication-TileColor" content="#000000" />
<meta name="msapplication-TileImage" content="/mstile-144x144.png" />
<meta name="msapplication-config" content="/browserconfig.xml" />
<meta name="theme-color" content="#000000" />
</head>
<body>
<body style="background-color:#000;">
<section id="coriolis">
<div class="modal">
<h2>
Please migrate to <a href="https://coriolis.io">coriolis.io</a>
</h2>
You are currently on coriolis.<strong>.edcd</strong>.io This domain is
considered deprecated. To migrate your builds, copy the below text and
go to
<a
target="_blank"
rel="noopener noreferrer"
href="https://coriolis.io"
>this link</a
>, press ctrl + i and then paste in the data. (If you are on mobile,
you can go to the settings and hit import)
<div>
<textarea id="data" class="cb json"></textarea>
</div>
</div>
</section>
</body>
<script>
const LS = localStorage;
/**
* Safe localstorage get string
* @param {String} key key
* @return {String} The stored string
*/
function _getString(key) {
return LS ? LS.getItem(key) : null;
}
/**
* Safe localstorage get
* @param {String} key key
* @return {object | number} The stored data
*/
function _get(key) {
let str = _getString(key);
try {
return str ? JSON.parse(str) : null;
} catch (e) {
return null;
}
}
const textarea = document.querySelector("#data");
const data = {
builds: _get("builds") || {},
comparisons: _get("comparisons") || {},
insurance: _get("insurance") || "standard",
shipDiscount: _get("shipDiscount") || 0,
moduleDiscount: _get("moduleDiscount") || 0
};
textarea.textContent = JSON.stringify(data, null, 2);
</script>
</body>
</html>