Compare commits

..

85 Commits

Author SHA1 Message Date
Danny Coates
8242e2088d bump version 2018-05-21 13:59:46 -07:00
emily-hou1
48457f7ac1 Merge pull request #817 from mozilla/i798
fixes #798
2018-05-21 13:28:52 -07:00
Emily Hou
8a496022f4 fixes #798 2018-05-21 13:20:33 -07:00
pyup.io bot
9c398ad98b Update selenium from 3.11.0 to 3.12.0 (#816) 2018-05-14 12:05:18 -04:00
pyup.io bot
dc1b754692 Scheduled weekly dependency update for week 18 (#815)
* Update pypom from 1.3.0 to 2.0.0

* Update pytest from 3.5.0 to 3.5.1

* Update pytest-html from 1.16.1 to 1.17.0
2018-05-07 13:22:08 -04:00
Joergen
dc7203ea59 Pontoon: Update Danish (da) localization of Test Pilot: Firefox Send
Localization authors:
- Joergen <joergenr@stofanet.dk>
- Kim Ludvigsen <kim@kimsside.dk>
2018-05-07 08:51:26 +00:00
chilledfrogs
af9973e35b Pontoon: Update Danish (da) localization of Test Pilot: Firefox Send
Localization authors:
- Joergen <joergenr@stofanet.dk>
- chilledfrogs <chilledfrogs@gmail.com>
2018-05-07 08:31:49 +00:00
Danny Coates
aeb44379c8 Merge pull request #813 from mozilla/docker-int
moved integration text execution to docker
2018-05-04 12:18:54 -07:00
Danny Coates
7841dec5d8 more docker integration test tweaks 2018-05-04 09:18:43 -07:00
Danny Coates
7d62a23b36 moved integration text execution to docker 2018-05-03 16:41:50 -07:00
Cristian Silaghi
f36ac24ac5 Pontoon: Update Romanian (ro) localization of Test Pilot: Firefox Send
Localization authors:
- Cristian Silaghi <cristian.silaghi@mozilla.ro>
2018-05-01 20:50:43 +00:00
Cristian Silaghi
e6c2736f1f Pontoon: Update Romanian (ro) localization of Test Pilot: Firefox Send
Localization authors:
- Cristian Silaghi <cristian.silaghi@mozilla.ro>
2018-05-01 20:30:53 +00:00
Selim Şumlu
0d46997ab3 Pontoon: Update Turkish (tr) localization of Test Pilot: Firefox Send
Localization authors:
- Selim Şumlu <selim@sum.lu>
2018-05-01 00:31:26 +00:00
Georgianizator
896a0f035b Pontoon: Update Georgian (ka) localization of Test Pilot: Firefox Send
Localization authors:
- Georgianizator <georgianization@outlook.com>
2018-04-30 17:31:32 +00:00
Georgianizator
fdd07a06be Pontoon: Update Georgian (ka) localization of Test Pilot: Firefox Send
Localization authors:
- Georgianizator <georgianization@outlook.com>
2018-04-30 17:11:21 +00:00
Rhoslyn Prys
8f8595e750 Pontoon: Update Welsh (cy) localization of Test Pilot: Firefox Send
Localization authors:
- Rhoslyn Prys <rprys@posteo.net>
2018-04-30 10:31:55 +00:00
Mozilla Pontoon
7a83fc6d8f Pontoon: Update Welsh (cy) localization of Test Pilot: Firefox Send 2018-04-30 07:34:31 +00:00
Mozilla Pontoon
30df33e189 Pontoon: Update Turkish (tr) localization of Test Pilot: Firefox Send 2018-04-30 07:34:23 +00:00
Mozilla Pontoon
7aac0426e0 Pontoon: Update Persian (fa) localization of Test Pilot: Firefox Send 2018-04-30 07:34:18 +00:00
Mozilla Pontoon
bc423d4d78 Pontoon: Update Georgian (ka) localization of Test Pilot: Firefox Send 2018-04-30 07:34:13 +00:00
hi
3ddfc822d1 Pontoon: Update Vietnamese (vi) localization of Test Pilot: Firefox Send
Localization authors:
- hi <hi@duonganhtuan.com>
- Trung Backup <backup.36a91519+tech@gmail.com>
2018-04-30 01:31:08 +00:00
Benjamin Forehand Jr
f99e4db25f Added footer link tests. (#811) 2018-04-27 15:44:03 -04:00
pyup.io bot
fd71e7f957 Config file for pyup.io (#809)
* create pyup.io config file

* Updated requirements directory.
2018-04-26 15:03:57 -04:00
paul.trevor
2bfeb75380 Pontoon: Update German (de) localization of Test Pilot: Firefox Send
Localization authors:
- paul.trevor <paul.trevor@gmx.de>
2018-04-25 07:11:48 +00:00
Danny Coates
21f7fd7dbc Merge pull request #800 from jrbenny35/add_initial_ui_tests
Initial user integration tests.
2018-04-24 13:34:34 -07:00
Benjamin Forehand Jr
3e08c35740 Updated strings and descriptions. 2018-04-24 11:07:11 -04:00
Benjamin Forehand Jr
54e78b6274 This adds some user integration tests to aide the SoftVision team a bit. Right now I have 3 tests.
test_upload: This will create a file and make sure it uploads by verifying a file uploads and is assigned a URL.

    test_download: This will create a file, upload it and then download it making sure it is the same filename that was uploaded. We can expand this later to maybe check the sizes and such.

    test_progress: This will create a file and make sure the progress bar shows up after it begins uploading.

    These are python tests and use Pipenv to manage dependencies as well as tox as the virtualenv manager, and finally pytest as the test runner.
2018-04-24 11:00:19 -04:00
Victor Bychek
f1499abbe8 Pontoon: Update Russian (ru) localization of Test Pilot: Firefox Send
Localization authors:
- Victor Bychek <a@bychek.ru>
- mail <mail@janitorrb.com>
2018-04-20 18:11:05 +00:00
Yongmin H
1ad78e2844 Pontoon: Update Korean (ko) localization of Test Pilot: Firefox Send
Localization authors:
- Yongmin H. <firefox@kumul.pe.kr>
2018-04-19 01:51:11 +00:00
eljuno
af436f9506 Pontoon: Update Indonesian (id) localization of Test Pilot: Firefox Send
Localization authors:
- eljuno <eljunotrie_anggoro@yahoo.co.id>
2018-04-16 20:11:06 +00:00
eljuno
4dfdc8b0c7 Pontoon: Update Indonesian (id) localization of Test Pilot: Firefox Send
Localization authors:
- eljuno <eljunotrie_anggoro@yahoo.co.id>
2018-04-15 18:31:25 +00:00
eljuno
b4c0c36f3a Pontoon: Update Indonesian (id) localization of Test Pilot: Firefox Send
Localization authors:
- eljuno <eljunotrie_anggoro@yahoo.co.id>
2018-04-12 19:32:37 +00:00
Sahithi
d52ca850cb Pontoon: Update Telugu (te) localization of Test Pilot: Firefox Send
Localization authors:
- Sahithi <sahithi.thinker@gmail.com>
2018-04-10 09:50:44 +00:00
Jordi Serratosa
c3e0787d12 Pontoon: Update Catalan (ca) localization of Test Pilot: Firefox Send
Localization authors:
- Jordi Serratosa <jordis@softcatala.cat>
2018-04-09 00:11:02 +00:00
Danny Coates
3f65e55f86 Merge pull request #801 from robtec/patch-2
Update faq.md
2018-04-07 19:07:59 -08:00
Rob Powell
2db56fac3a Update faq.md
Updated information around download limits
2018-04-07 23:21:55 +01:00
Cristian Silaghi
464c0c4c47 Pontoon: Update Romanian (ro) localization of Test Pilot: Firefox Send
Localization authors:
- Cristian Silaghi <cristian.silaghi@mozilla.ro>
2018-04-03 12:11:31 +00:00
Danny Coates
71ed7d71fb added browserstack badge to readme 2018-03-31 19:50:45 -07:00
Danny Coates
cda38f9bcf v2.5.3 2018-03-29 00:03:04 -07:00
Danny Coates
cc9b622bde fixed cryptofill on edge 2018-03-28 22:03:46 -07:00
Danny Coates
fb91fd03cc adjusted selectbox styles 2018-03-27 23:19:07 -07:00
rcmainak
77e3b5a3e6 Replaced the selectbox with native HTML <select> 2018-03-27 21:40:59 -07:00
صفا الفليج
0ed5c7f1e7 Pontoon: Update Arabic (ar) localization of Test Pilot: Firefox Send
Localization authors:
- صفا الفليج <safa1996alfulaij@gmail.com>
2018-03-26 01:32:08 +00:00
Alberto Castro
5afadd4ff1 Pontoon: Update Portuguese (Portugal) (pt-PT) localization of Test Pilot: Firefox Send
Localization authors:
- Alberto Castro <albertdcastro@gmail.com>
- Rodrigo <rodrigo.mcunha@hotmail.com>
2018-03-22 17:10:58 +00:00
వీవెన్
0f53c718a2 Pontoon: Update Telugu (te) localization of Test Pilot: Firefox Send
Localization authors:
- వీవెన్ <veeven@gmail.com>
2018-03-22 16:31:46 +00:00
Gonçalo Matos
ad4e6c8dec Pontoon: Update Portuguese (Portugal) (pt-PT) localization of Test Pilot: Firefox Send
Localization authors:
- Alberto Castro <albertdcastro@gmail.com>
- Gonçalo Matos <goncalo.matos@me.com>
- Rodrigo <rodrigo.mcunha@hotmail.com>
2018-03-22 02:31:41 +00:00
Rodrigo
9e0195deaa Pontoon: Update Portuguese (Portugal) (pt-PT) localization of Test Pilot: Firefox Send
Localization authors:
- Rodrigo <rodrigo.mcunha@hotmail.com>
2018-03-22 02:12:00 +00:00
Rodrigo
253216e6fc Pontoon: Update Portuguese (Portugal) (pt-PT) localization of Test Pilot: Firefox Send
Localization authors:
- Rodrigo <rodrigo.mcunha@hotmail.com>
2018-03-21 20:10:48 +00:00
Roberto Alvarado
78eab6335d Pontoon: Update Spanish (Mexico) (es-MX) localization of Test Pilot: Firefox Send
Localization authors:
- Roberto Alvarado <ralv888@gmail.com>
2018-03-19 22:11:09 +00:00
Enol
1d20b5ba11 Pontoon: Update Asturian (ast) localization of Test Pilot: Firefox Send
Localization authors:
- Enol <enolp@softastur.org>
2018-03-15 15:11:13 +00:00
Danny Coates
1edc571b36 v2.5.2 2018-03-14 09:12:26 -07:00
Danny Coates
e3556aa7e1 updated cryptofill to support Android Firefox. fixes #790 2018-03-13 21:11:27 -07:00
Jobava
aa94a75da9 Pontoon: Update Romanian (ro) localization of Test Pilot: Firefox Send
Localization authors:
- Jobava <jobaval10n@gmail.com>
2018-03-13 20:51:11 +00:00
Danny Coates
ecd61830aa v2.5.1 2018-03-12 12:26:37 -07:00
Danny Coates
da82ef814b MS Edge hacks 2018-03-12 12:24:43 -07:00
Danny Coates
b840173429 Merge pull request #789 from RCMainak/issue_775
Fixed #775 : Made text not-selectable
2018-03-12 10:43:53 -07:00
rcmainak
e1dc1687fc Fixed #775 : Made text not-selectable 2018-03-12 23:09:00 +05:30
Danny Coates
3e6a88d31d render header and footer only once. fixes #788 2018-03-12 10:15:11 -07:00
Melo46
94714ecb62 Pontoon: Update Interlingua (ia) localization of Test Pilot: Firefox Send
Localization authors:
- Melo46 <melo@carmu.com>
2018-03-09 00:50:44 +00:00
Danny Coates
07a817266c v2.5.0 2018-03-08 11:31:35 -08:00
Vitaliy Krutko
706708876c Pontoon: Update Ukrainian (uk) localization of Test Pilot: Firefox Send
Localization authors:
- Vitaliy Krutko <asmforce@ukr.net>
2018-03-08 17:52:01 +00:00
Frederick Villaluna
fc4cbe4b74 Pontoon: Update Tagalog (tl) localization of Test Pilot: Firefox Send
Localization authors:
- Frederick Villaluna <fv_comscie@yahoo.com>
2018-03-08 17:51:57 +00:00
ravmn
9e8429cff3 Pontoon: Update Spanish (Chile) (es-CL) localization of Test Pilot: Firefox Send
Localization authors:
- ravmn <ravmn@ravmn.cl>
2018-03-08 17:51:54 +00:00
Gabriela
f8db7ca923 Pontoon: Update Spanish (Argentina) (es-AR) localization of Test Pilot: Firefox Send
Localization authors:
- Gabriela <gmontagu@gmail.com>
2018-03-08 17:51:51 +00:00
Rok Žerdin
70e4d9eeb0 Pontoon: Update Slovenian (sl) localization of Test Pilot: Firefox Send
Localization authors:
- Rok Žerdin <rok.zerdin1990@gmail.com>
2018-03-08 17:51:48 +00:00
Jobava
410ec72fff Pontoon: Update Romanian (ro) localization of Test Pilot: Firefox Send
Localization authors:
- Jobava <jobaval10n@gmail.com>
2018-03-08 17:51:45 +00:00
Arash Mousavi
a42a517896 Pontoon: Update Persian (fa) localization of Test Pilot: Firefox Send
Localization authors:
- Arash Mousavi <mousavi.arash@gmail.com>
2018-03-08 17:51:42 +00:00
Håvar Henriksen
d9c9d95b89 Pontoon: Update Norwegian Bokmål (nb-NO) localization of Test Pilot: Firefox Send
Localization authors:
- Håvar Henriksen <havar@firefox.no>
2018-03-08 17:51:39 +00:00
Alfredos-Panagiotis Damkalis
0ed10649ef Pontoon: Update Greek (el) localization of Test Pilot: Firefox Send
Localization authors:
- Alfredos-Panagiotis Damkalis <fredy@fredy.gr>
2018-03-08 17:51:36 +00:00
Fjoerfoks
4edf82cc21 Pontoon: Update Frisian (fy-NL) localization of Test Pilot: Firefox Send
Localization authors:
- Fjoerfoks <fryskefirefox@gmail.com>
2018-03-08 17:51:33 +00:00
Merike Sell
775726ae6d Pontoon: Update Estonian (et) localization of Test Pilot: Firefox Send
Localization authors:
- Merike Sell <merikes@gmail.com>
2018-03-08 17:51:30 +00:00
Michal Vašíček
5aeaf2e987 Pontoon: Update Czech (cs) localization of Test Pilot: Firefox Send
Localization authors:
- Michal Vašíček <michalvasicek@icloud.com>
- Michal Stanke <mstanke@mozilla.cz>
2018-03-08 17:51:27 +00:00
Emin Mastizada
773244f320 Pontoon: Update Azerbaijani (az) localization of Test Pilot: Firefox Send
Localization authors:
- Emin Mastizada <emin@mastizada.com>
2018-03-08 17:51:23 +00:00
Danny Coates
5079d9a317 Merge pull request #782 from mozilla/docs
updated docs
2018-03-07 15:20:11 -08:00
Danny Coates
18e1609cb3 updated docs 2018-03-07 15:01:08 -08:00
Danny Coates
41796840c4 Merge pull request #781 from timvisee/master
Don't translate URL-safe chars, b64 is doing it for us
2018-03-06 08:44:53 -08:00
timvisee
171b64bc98 Don't translate URL-safe chars, b64 is doing it for us 2018-03-06 14:38:29 +01:00
Danny Coates
cfc94fd9af built assets are webpack cacheable 2018-03-02 13:58:05 -08:00
Danny Coates
914394054e encapsulate translate function creation 2018-03-02 13:40:29 -08:00
Danny Coates
7a237b9b68 reduced the size of cryptofill 2018-03-02 12:21:59 -08:00
Danny Coates
80e9f129d8 ignore some lint warnings 2018-03-01 21:36:45 -08:00
Danny Coates
fddf1c40dc fixed password input style on small screens 2018-03-01 21:33:59 -08:00
Danny Coates
557db53d39 updated browserlist 2018-03-01 14:52:00 -08:00
Danny Coates
c16e00e5af Merge pull request #779 from mozilla/edgy
implemented crypto polyfills for ms edge
2018-03-01 13:21:45 -08:00
Danny Coates
cd7da20024 implemented crypto polyfills for ms edge 2018-03-01 13:10:57 -08:00
103 changed files with 1827 additions and 612 deletions

View File

@@ -1,5 +1,6 @@
node_modules
.git
.tox
.DS_Store
firefox
assets
@@ -7,4 +8,4 @@ docs
public
test
coverage
.nyc_output
.nyc_output

4
.gitignore vendored
View File

@@ -3,4 +3,6 @@ coverage
dist
.idea
.DS_Store
.nyc_output
.nyc_output
.tox
.pytest_cache

7
.pyup.yml Normal file
View File

@@ -0,0 +1,7 @@
# autogenerated pyup.io config file
# see https://pyup.io/docs/configuration/ for all available options
schedule: every week
requirements:
- test/integration/Pipfile
- test/integration/pipenv.txt

View File

@@ -1,6 +1,17 @@
## Change Log
### upcoming (2018/02/27 01:52 +00:00)
### v2.5.1 (2018/03/12 19:26 +00:00)
- [#789](https://github.com/mozilla/send/pull/789) Fixed #775 : Made text not-selectable (@RCMainak)
### v2.5.0 (2018/03/08 19:31 +00:00)
- [#782](https://github.com/mozilla/send/pull/782) updated docs (@dannycoates)
- [#781](https://github.com/mozilla/send/pull/781) Don't translate URL-safe chars, b64 is doing it for us (@timvisee)
- [#779](https://github.com/mozilla/send/pull/779) implemented crypto polyfills for ms edge (@dannycoates)
### v2.4.1 (2018/02/28 17:05 +00:00)
- [#777](https://github.com/mozilla/send/pull/777) use a separate circle in the progress svg for indefinite progress (@dannycoates)
### v2.4.0 (2018/02/27 01:55 +00:00)
- [#769](https://github.com/mozilla/send/pull/769) removed unsafe-inline styles via svgo-loader (@dannycoates)
- [#767](https://github.com/mozilla/send/pull/767) added coverage artifact to circleci (@dannycoates)
- [#766](https://github.com/mozilla/send/pull/766) Some frontend unit tests [WIP] (@dannycoates)

View File

@@ -3,6 +3,7 @@ Abhinav Adduri
Adnan Kičin
Alberto Castro
Alexander Slovesnik
Alfredos-Panagiotis Damkalis
Amin Mahmudian
Andreas Pettersson
Arash Mousavi
@@ -33,8 +34,10 @@ Fjoerfoks
Francesco Lodolo
Francesco Lodolo [:flod]
Frederick Villaluna
Gabriela
Gautam krishna.R
Georgianizator
Gonçalo Matos
Hyeonseok Shin
Håvar Henriksen
Jae Hyeon Park
@@ -111,6 +114,7 @@ Tymur Faradzhev
Uccen Marzuq
Varghese Thomas
Victor Bychek
Vitaliy Krutko
Weihang Lo
Wil Clouser
YFdyh000
@@ -137,14 +141,17 @@ kenrick95
manxmensch
mirzet.omerovic.1992
ravmn
rcmainak
reza.habibi2008
savemore99.sm
shikhar-scs
siparon
skystar-p
tiagomoraismorgado
timvisee
xcffl
ybouhamam
Μιχάλης
Марко Костић (Marko Kostić)
صفا الفليج
వీవెన్

View File

@@ -1,9 +1,10 @@
# Firefox Send
[![BrowserStack Status](https://www.browserstack.com/automate/badge.svg?badge_key=aFFIMHNEWFcrNHJaMU1LRkJnUDhOQkNHMmh2WHBscjJsZHcwK1h0dkhwdz0tLXRpN1RXcysybUtxTFFTVGRtWjVGeHc9PQ==--c56129be8c75941b115c5b5e5d3ed10b3c7dca6b)](https://www.browserstack.com/automate/public-build/aFFIMHNEWFcrNHJaMU1LRkJnUDhOQkNHMmh2WHBscjJsZHcwK1h0dkhwdz0tLXRpN1RXcysybUtxTFFTVGRtWjVGeHc9PQ==--c56129be8c75941b115c5b5e5d3ed10b3c7dca6b)
[![CircleCI](https://img.shields.io/circleci/project/github/mozilla/send.svg)](https://circleci.com/gh/mozilla/send)
[![Available on Test Pilot](https://img.shields.io/badge/available_on-Test_Pilot-0996F8.svg)](https://testpilot.firefox.com/experiments/send)
**Docs:** [Docker](docs/docker.md), [Metrics](docs/metrics.md)
**Docs:** [FAQ](docs/faq.md), [Encryption](docs/encryption.md), [Build](docs/build.md), [Docker](docs/docker.md), [Metrics](docs/metrics.md), [More](docs/)
---
@@ -71,6 +72,8 @@ The server is configured with environment variables. See [server/config.js](serv
Firefox Send localization is managed via [Pontoon](https://pontoon.mozilla.org/projects/test-pilot-firefox-send/), not direct pull requests to the repository. If you want to fix a typo, add a new language, or simply know more about localization, please get in touch with the [existing localization team](https://pontoon.mozilla.org/teams/) for your language or Mozillas [l10n-drivers](https://wiki.mozilla.org/L10n:Mozilla_Team#Mozilla_Corporation) for guidance.
see also [docs/localization.md](docs/localization.md)
---
## Contributing

View File

@@ -123,6 +123,7 @@ a {
cursor: pointer;
/* Force flat button look */
/* stylelint-disable-next-line plugin/no-unsupported-browser-features */
appearance: none;
font-size: 15px;
padding-bottom: 3px;

View File

@@ -19,6 +19,7 @@ export default function(state, emitter) {
return;
}
if (target.files.length > 1) {
// eslint-disable-next-line no-alert
return alert(state.translate('uploadPageMultipleFilesAlert'));
}
const file = target.files[0];
@@ -26,9 +27,8 @@ export default function(state, emitter) {
return;
}
if (file.size > MAXFILESIZE) {
window.alert(
state.translate('fileTooBig', { size: bytes(MAXFILESIZE) })
);
// eslint-disable-next-line no-alert
alert(state.translate('fileTooBig', { size: bytes(MAXFILESIZE) }));
return;
}
emitter.emit('upload', { file, type: 'drop' });

View File

@@ -104,24 +104,27 @@ export default function(state, emitter) {
metrics.completedUpload(ownedFile);
state.storage.addFile(ownedFile);
document.getElementById('cancel-upload').hidden = 'hidden';
const cancelBtn = document.getElementById('cancel-upload');
if (cancelBtn) {
cancelBtn.hidden = 'hidden';
}
await delay(1000);
await fadeOut('.page');
openLinksInNewTab(links, false);
emitter.emit('pushState', `/share/${ownedFile.id}`);
} catch (err) {
console.error(err);
if (err.message === '0') {
//cancelled. do nothing
metrics.cancelledUpload({ size, type });
return render();
render();
} else {
// eslint-disable-next-line no-console
console.error(err);
state.raven.captureException(err);
metrics.stoppedUpload({ size, type, err });
emitter.emit('pushState', '/error');
}
state.raven.captureException(err);
metrics.stoppedUpload({ size, type, err });
emitter.emit('pushState', '/error');
} finally {
openLinksInNewTab(links, false);
state.uploading = false;
state.transfer = null;
}
@@ -136,6 +139,7 @@ export default function(state, emitter) {
metrics.addedPassword({ size: file.size });
await delay(1000);
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);
state.passwordSetError = err;
} finally {
@@ -184,16 +188,18 @@ export default function(state, emitter) {
if (err.message === '0') {
// download cancelled
state.transfer.reset();
return render();
render();
} else {
// eslint-disable-next-line no-console
console.error(err);
state.transfer = null;
const location = err.message === '404' ? '/404' : '/error';
if (location === '/error') {
state.raven.captureException(err);
metrics.stoppedDownload({ size, err });
}
emitter.emit('pushState', location);
}
console.error(err);
state.transfer = null;
const location = err.message === '404' ? '/404' : '/error';
if (location === '/error') {
state.raven.captureException(err);
metrics.stoppedDownload({ size, err });
}
emitter.emit('pushState', location);
} finally {
openLinksInNewTab(links, false);
}

View File

@@ -78,10 +78,11 @@ export default class FileSender extends Nanobus {
this.keychain,
p => {
this.progress = p;
this.emit('progress', p);
this.emit('progress');
}
);
this.msg = 'fileSizeProgress';
this.emit('progress'); // HACK to kick MS Edge
try {
const result = await this.uploadRequest.result;
const time = Date.now() - start;

View File

@@ -1,10 +1,10 @@
import 'fast-text-encoding'; // MS Edge support
import 'fluent-intl-polyfill';
import app from './routes';
import locale from '../common/locales';
import fileManager from './fileManager';
import dragManager from './dragManager';
import { canHasSend } from './utils';
import assets from '../common/assets';
import storage from './storage';
import metrics from './metrics';
import experiments from './experiments';
@@ -30,10 +30,7 @@ app.use((state, emitter) => {
) {
unsupportedReason = 'outdated';
}
if (/edge\/\d+/i.test(navigator.userAgent)) {
unsupportedReason = 'edge';
}
const ok = await canHasSend(assets.get('cryptofill.js'));
const ok = await canHasSend();
if (!ok) {
unsupportedReason = /firefox/i.test(navigator.userAgent)
? 'outdated'

View File

@@ -16,7 +16,7 @@ module.exports = function(state, emit) {
return html`
<div id="shareWrapper" class="effect--fadeIn">
<div class="title">${expireInfo(file, state.translate, emit)}</div>
${expireInfo(file, state.translate, emit)}
<div class="sharePage">
<div class="sharePage__copyText">
${state.translate('copyUrlFormLabelWithName', { filename: file.name })}
@@ -97,7 +97,7 @@ module.exports = function(state, emit) {
function expireInfo(file, translate, emit) {
const hours = Math.floor(EXPIRE_SECONDS / 60 / 60);
const el = html`<div>${raw(
const el = html`<div class="title">${raw(
translate('expireInfo', {
downloadCount: '<select></select>',
timespan: translate('timespanHours', { num: hours })
@@ -107,9 +107,6 @@ function expireInfo(file, translate, emit) {
const options = [1, 2, 3, 4, 5, 20].filter(i => i > (file.dtotal || 0));
const t = num => translate('downloadCount', { num });
const changed = value => emit('changeLimit', { file, value });
select.parentNode.replaceChild(
selectbox(file.dlimit || 1, options, t, changed),
select
);
el.replaceChild(selectbox(file.dlimit || 1, options, t, changed), select);
return el;
}

View File

@@ -73,7 +73,8 @@ module.exports = function(state, emit) {
return;
}
if (file.size > MAXFILESIZE) {
window.alert(state.translate('fileTooBig', { size: bytes(MAXFILESIZE) }));
// eslint-disable-next-line no-alert
alert(state.translate('fileTooBig', { size: bytes(MAXFILESIZE) }));
return;
}

9
app/readme.md Normal file
View File

@@ -0,0 +1,9 @@
# Application Code
`app/` contains the browser code that gets bundled into `app.[hash].js`. It's got all the logic, crypto, and UI. All of it gets used in the browser, and some of it by the server for server side rendering.
The main entrypoint for the browser is [main.js](./main.js) and on the server [routes/index.js](./routes/index.js) gets imported by [/server/routes/pages.js](../server/routes/pages.js)
- `pages` contains display logic an markup for pages
- `routes` contains route definitions and logic
- `templates` contains ui elements smaller than pages

View File

@@ -2,7 +2,7 @@ const html = require('choo/html');
const assets = require('../../../common/assets');
module.exports = function(state) {
return html`<footer class="footer">
const footer = html`<footer class="footer">
<div class="legalSection">
<a
href="https://www.mozilla.org"
@@ -61,4 +61,11 @@ module.exports = function(state) {
</a>
</div>
</footer>`;
// HACK
// We only want to render this once because we
// toggle the targets of the links with utils/openLinksInNewTab
footer.isSameNode = function(target) {
return target && target.nodeName && target.nodeName === 'FOOTER';
};
return footer;
};

View File

@@ -15,24 +15,32 @@ const browser = browserName();
module.exports = function(state) {
const feedbackUrl = `https://qsurvey.mozilla.com/s3/txp-firefox-send?ver=${version}&browser=${browser}`;
return html`<header class="header">
<div class="logo">
<a class="logo__link" href="/">
<img
src="${assets.get('send_logo.svg')}"
alt="Send"/>
<h1 class="logo__title">Send</h1>
</a>
<div class="logo__subtitle">
<a class="logo__subtitle-link" href="https://testpilot.firefox.com">Firefox Test Pilot</a>
<div>${state.translate('siteSubtitle')}</div>
const header = html`
<header class="header">
<div class="logo">
<a class="logo__link" href="/">
<img
src="${assets.get('send_logo.svg')}"
alt="Send"/>
<h1 class="logo__title">Send</h1>
</a>
<div class="logo__subtitle">
<a class="logo__subtitle-link" href="https://testpilot.firefox.com">Firefox Test Pilot</a>
<div>${state.translate('siteSubtitle')}</div>
</div>
</div>
</div>
<a href="${feedbackUrl}"
rel="noreferrer noopener"
class="feedback"
target="_blank">${state.translate('siteFeedback')}</a>
</header>`;
<a href="${feedbackUrl}"
rel="noreferrer noopener"
class="feedback"
target="_blank">${state.translate('siteFeedback')}</a>
</header>`;
// HACK
// We only want to render this once because we
// toggle the targets of the links with utils/openLinksInNewTab
header.isSameNode = function(target) {
return target && target.nodeName && target.nodeName === 'HEADER';
};
return header;
};
function browserName() {

View File

@@ -35,8 +35,7 @@
}
@media (max-device-width: 520px), (max-width: 520px) {
.passwordInput {
.passwordInput__form {
flex-direction: column;
width: inherit;
}
}

View File

@@ -7,6 +7,10 @@ const oDiameter = oRadius * 2;
const circumference = 2 * Math.PI * radius;
module.exports = function(progressRatio, indefinite = false) {
// HACK - never indefinite for MS Edge
if (/edge/i.test(navigator.userAgent)) {
indefinite = false;
}
const p = indefinite ? 0.2 : progressRatio;
const dashOffset = (1 - p) * circumference;
const progressPercent = html`

View File

@@ -1,59 +1,28 @@
const html = require('choo/html');
const number = require('../../utils').number;
module.exports = function(selected, options, translate, changed) {
const id = `select-${Math.random()}`;
let x = selected;
return html`
<div class="selectbox">
<div onclick=${toggle}>
<span class="link">${translate(selected)}</span>
<svg width="32" height="32">
<polygon points="8 18 17 28 26 18" fill="#0094fb"/>
</svg>
</div>
<ul id="${id}" class="selectbox__options">
<div class="select">
<select id="${id}" onchange=${choose}>
${options.map(
i => html`
<li
class="selectbox__option"
onclick=${choose}
data-value="${i}">${number(i)}</li>`
i =>
html`<option value="${i}" ${
i === selected ? 'selected' : ''
}>${translate(i)}</option>`
)}
</ul>
</select>
</div>`;
function close() {
const ul = document.getElementById(id);
const body = document.querySelector('body');
ul.classList.remove('selectbox__options--active');
body.removeEventListener('click', close);
}
function toggle(event) {
event.stopPropagation();
const ul = document.getElementById(id);
if (ul.classList.contains('selectbox__options--active')) {
close();
} else {
ul.classList.add('selectbox__options--active');
const body = document.querySelector('body');
body.addEventListener('click', close);
}
}
function choose(event) {
event.stopPropagation();
const target = event.target;
const value = +target.dataset.value;
target.parentNode.previousSibling.firstElementChild.textContent = translate(
value
);
const value = +target.value;
if (x !== value) {
x = value;
changed(value);
}
close();
}
};

View File

@@ -1,36 +1,47 @@
.selectbox {
display: inline-block;
position: relative;
cursor: pointer;
}
.selectbox__options {
display: none;
}
.selectbox__options--active {
display: block;
position: absolute;
top: 0;
left: 0;
padding: 0;
margin: 40px 0;
.select {
background-color: var(--pageBGColor);
border: 1px solid rgba(12, 12, 13, 0.3);
overflow: hidden;
padding: 4px 2px 4px 2px;
border: 1px dotted #0094fb88;
border-radius: 4px;
box-shadow: 1px 2px 4px rgba(12, 12, 13, 0.3);
display: inline;
position: relative;
}
.selectbox__option {
color: var(--lightTextColor);
font-size: 12pt;
list-style: none;
user-select: none;
white-space: nowrap;
padding: 0 60px;
border-bottom: 1px solid rgba(12, 12, 13, 0.3);
.select::after {
color: #0094fb;
content: '\25BC';
position: absolute;
right: 0;
padding: 0 10px;
pointer-events: none;
font-size: 20px;
}
.selectbox__option:hover {
background-color: #f4f4f4;
option {
padding: 0;
}
select {
appearance: none;
outline: 0;
box-shadow: none;
border: 0;
background: #fff;
background-image: none;
font-size: 1em;
font-weight: 200;
margin: 0;
color: #0094fb;
cursor: pointer;
padding-right: 40px;
}
select:active {
background-color: var(--pageBGColor);
border: 0;
}
#arrow {
position: relative;
}

View File

@@ -17,6 +17,7 @@
line-height: 23px;
cursor: pointer;
color: var(--lightTextColor);
user-select: none;
}
.checkbox__label::before {

View File

@@ -9,10 +9,7 @@ function arrayToB64(array) {
}
function b64ToArray(str) {
str = (str + '==='.slice((str.length + 3) % 4))
.replace(/-/g, '+')
.replace(/_/g, '/');
return b64.toByteArray(str);
return b64.toByteArray(str + '==='.slice((str.length + 3) % 4));
}
function loadShim(polyfill) {
@@ -25,7 +22,7 @@ function loadShim(polyfill) {
});
}
async function canHasSend(polyfill) {
async function canHasSend() {
try {
const key = await window.crypto.subtle.generateKey(
{
@@ -35,7 +32,6 @@ async function canHasSend(polyfill) {
true,
['encrypt', 'decrypt']
);
await window.crypto.subtle.encrypt(
{
name: 'AES-GCM',
@@ -45,9 +41,24 @@ async function canHasSend(polyfill) {
key,
new ArrayBuffer(8)
);
await window.crypto.subtle.importKey(
'raw',
window.crypto.getRandomValues(new Uint8Array(16)),
'PBKDF2',
false,
['deriveKey']
);
await window.crypto.subtle.importKey(
'raw',
window.crypto.getRandomValues(new Uint8Array(16)),
'HKDF',
false,
['deriveKey']
);
return true;
} catch (err) {
return loadShim(polyfill);
console.error(err);
return false;
}
}
@@ -167,6 +178,7 @@ module.exports = {
copyToClipboard,
arrayToB64,
b64ToArray,
loadShim,
canHasSend,
isFile,
openLinksInNewTab

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,5 @@
last 2 chrome versions
last 2 firefox versions
last 2 safari versions
last 2 edge versions
firefox esr
safari > 9

View File

@@ -42,20 +42,22 @@ if (typeof window === 'undefined') {
require('babel-polyfill');
var fluent = require('fluent/compat');
}
var fluentContext = new fluent.MessageContext('${locale}', {useIsolating: false});
fluentContext._messages = new Map(${toJSON(merged)});
function translate(id, data) {
var msg = fluentContext.getMessage(id);
if (typeof(msg) !== 'string' && !msg.val && msg.attrs) {
msg = msg.attrs.title || msg.attrs.alt
(function () {
var ctx = new fluent.MessageContext('${locale}', {useIsolating: false});
ctx._messages = new Map(${toJSON(merged)});
function translate(id, data) {
var msg = ctx.getMessage(id);
if (typeof(msg) !== 'string' && !msg.val && msg.attrs) {
msg = msg.attrs.title || msg.attrs.alt
}
return ctx.format(msg, data);
}
return fluentContext.format(msg, data);
}
if (typeof window === 'undefined') {
module.exports = translate;
}
else {
window.translate = translate;
}
if (typeof window === 'undefined') {
module.exports = translate;
}
else {
window.translate = translate;
}
})();
\``;
};

View File

@@ -1,3 +1,14 @@
/*
This code is included by both the server and frontend via
common/assets.js
When included from the server the export will be the function.
When included from the frontend (via webpack) the export will
be an object mapping file names to hashed file names. Example:
"send_logo.svg": "send_logo.5fcfdf0e.svg"
*/
const fs = require('fs');
const path = require('path');
@@ -14,6 +25,6 @@ module.exports = function() {
return {
code,
dependencies: files.map(f => require.resolve('../assets/' + f)),
cacheable: false
cacheable: true
};
};

View File

@@ -1,3 +1,14 @@
/*
This code is included by both the server and frontend via
common/locales.js
When included from the server the export will be the function.
When included from the frontend (via webpack) the export will
be an object mapping ftl files to js files. Example:
"public/locales/en-US/send.ftl":"public/locales/en-US/send.6b4f8354.js"
*/
const fs = require('fs');
const path = require('path');
@@ -17,6 +28,6 @@ module.exports = function() {
dependencies: dirs.map(d =>
require.resolve(`../public/locales/${d}/send.ftl`)
),
cacheable: false
cacheable: true
};
};

26
build/readme.md Normal file
View File

@@ -0,0 +1,26 @@
# Custom Loaders
## Fluent Loader
The fluent loader "compiles" `.ftl` files into `.js` files directly usable by both the frontend and server for localization.
## Generate Asset Map
This loader enumerates all the files in `assets/` so that `common/assets.js` can provide mappings from the source filename to the hashed filename used on the site.
## Generate L10N Map
This loader enumerates all the ftl files in `public/locales` so that the fluent loader can create it's js files.
## Package.json Loader
This loader creates a `version.json` file that gets exposed by the `/__version__` route from the `package.json` file and current git commit hash.
## Version Loader
This loader substitutes the string "VERSION" for the version string specified in `package.json`. This is a workaround because `package.json` already uses the `package_json_loader`. See [app/templates/header/index.js](../app/templates/header/index.js) for more info.
# See Also
- [docs/build.md](../docs/build.md)
- [webpack.config.js](../webpack.config.js)

View File

@@ -16,7 +16,7 @@ jobs:
- persist_to_workspace:
root: .
paths:
- ./*
- ./dist
test:
docker:
- image: circleci/node:8-browsers
@@ -31,12 +31,29 @@ jobs:
- node_modules
- run: npm run check
- run: npm run lint
- run: npm test
- run: npm run test
- store_artifacts:
path: coverage
integration_tests:
machine: true
steps:
- checkout
- attach_workspace:
at: .
- run:
name: Install Docker Compose
command: |
set -x
pip install docker-compose>=1.18
docker-compose --version
- run:
command: npm run test-integration
- store_artifacts:
path: coverage/send-test.html
deploy_dev:
machine: true
steps:
- checkout
- attach_workspace:
at: .
- run: docker login -u $DOCKER_USER -p $DOCKER_PASS
@@ -45,6 +62,7 @@ jobs:
deploy_stage:
machine: true
steps:
- checkout
- attach_workspace:
at: .
- run: docker login -u $DOCKER_USER -p $DOCKER_PASS
@@ -54,10 +72,20 @@ workflows:
version: 2
test_pr:
jobs:
- build:
filters:
branches:
ignore: master
- test:
filters:
branches:
ignore: master
- integration_tests:
filters:
branches:
ignore: master
requires:
- build
build_and_deploy_dev:
jobs:
- build:
@@ -88,12 +116,21 @@ workflows:
ignore: /.*/
tags:
only: /^v.*/
- deploy_stage:
- integration_tests:
requires:
- build
- test
filters:
branches:
ignore: /.*/
tags:
only: /^v.*/
only: /^v.*/
- deploy_stage:
requires:
- build
- test
- integration_tests
filters:
branches:
ignore: /.*/
tags:
only: /^v.*/

View File

@@ -4,7 +4,7 @@ const isServer = typeof gen === 'function';
const prefix = isServer ? '/' : '';
let manifest = {};
try {
//eslint-disable-next-line node/no-missing-require
// eslint-disable-next-line node/no-missing-require
manifest = require('../dist/manifest.json');
} catch (e) {
// use middleware
@@ -17,6 +17,7 @@ function getLocale(name) {
}
function serverTranslator(name) {
// eslint-disable-next-line security/detect-non-literal-require
return require(`../dist/${locales[`public/locales/${name}/send.ftl`]}`);
}

3
common/readme.md Normal file
View File

@@ -0,0 +1,3 @@
# Common Code
This directory contains code loaded by both the frontend `app` and backend `server`. The code here can be challenging to understand at first because the contexts for the two (three counting the dev server) environments that include them are quite different, but the purpose of these modules are quite simple, to provide mappings from the source assets (`copy-16.png`) to the concrete production assets (`copy-16.db66e0bf.svg`), similarly for localizations.

View File

@@ -10,3 +10,17 @@ services:
- REDIS_HOST=redis
redis:
image: redis:alpine
selenium:
image: b4handjr/selenium-firefox
ports:
- "${VNC_PORT:-5900}:5900"
shm_size: 2g
integration-tests:
build: ./test/integration
environment:
- BASE_URL=${BASE_URL:-http://web:1443}
links:
- web
- selenium
volumes:
- "./coverage:/coverage"

22
docs/build.md Normal file
View File

@@ -0,0 +1,22 @@
Send has two build configurations, development and production. Both can be run via `npm` scripts, `npm start` for development and `npm run build` for production. Webpack is our only build tool and all configuration lives in [webpack.config.js](../webpack.config.js).
# Development
`npm start` launches a `webpack-dev-server` on port 8080 that compiles the assets and watches files for changes. It also serves the backend API and frontend unit tests via the `server/dev.js` entrypoint. The frontend tests can be run in the browser by navigating to http://localhost:8080/test and will rerun automatically as the watched files are saved with changes.
# Production
`npm run build` compiles the assets and writes the files to the `dist/` directory. `npm run prod` launches an Express server on port 1443 that serves the backend API and frontend static assets from `dist/` via the `server/prod.js` entrypoint.
# Notable differences
- Development compiles assets in memory, so no `dist/` directory is generated
- Development does not enable CSP headers
- Development frontend source is instrumented for code coverage
- Only development includes sourcemaps
- Only development exposes the `/test` route
- Production sets Cache-Control immutable headers on the hashed static assets
# Custom Loaders
The `build/` directory contains custom webpack loaders specific to Send. See [build/readme.md](../build/readme.md) for details on each loader.

46
docs/encryption.md Normal file
View File

@@ -0,0 +1,46 @@
# File Encryption
Send use 128-bit AES-GCM encryption via the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) to encrypt files in the browser before uploading them to the server. The code is in [app/keychain.js](../app/keychain.js).
## Steps
### Uploading
1. A new secret key is generated with `crypto.getRandomValues`
2. The secret key is used to derive 3 more keys via HKDF SHA-256
- an encryption key for the file (AES-GCM)
- an encryption key for the file metadata (AES-GCM)
- a signing key for request authentication (HMAC SHA-256)
3. The file and metadata are encrypted with their corresponding keys
4. The encrypted data and signing key are uploaded to the server
5. An owner token and the share url are returned by the server and stored in local storage
6. The secret key is appended to the share url as a [#fragment](https://en.wikipedia.org/wiki/Fragment_identifier) and presented to the UI
### Downloading
1. The browser loads the share url page, which includes an authentication nonce
2. The browser imports the secret key from the url fragment
3. The same 3 keys as above are derived
4. The browser signs the nonce with it's signing key and requests the metadata
5. The encrypted metadata is decrypted and presented on the page
6. The browser makes another authenticated request to download the encrypted file
7. The browser downloads and decrypts the file
8. The file prompts the save dialog or automatically saves depending on the browser settings
### Passwords
A password may optionally be set to authenticate the download request. When a password is set the following steps occur.
#### Sender
1. The original signing key derived from the secret key is discarded
2. A new signing key is generated via PBKDF2 from the user entered password and the full share url (including secret key fragment)
3. The new key is sent to the server, authenticated by the owner token
4. The server stores the new key and marks the record as needing a password
#### Downloader
1. The browser loads the share url page, which includes an authentication nonce and indicator that the file requires a password
2. The user is prompted for the password and the signing key is derived
3. The browser requests the metadata using the key to sign the nonce
4. If the password was correct the metadata is returned, otherwise a 401

84
docs/experiments.md Normal file
View File

@@ -0,0 +1,84 @@
# A/B experiment testing
We're using Google Analytics Experiments for A/B testing.
## Creating an experiment
Navigate to the Behavior > Experiments section of Google Analytics and click the "Create experiment" button.
The "Objective for this experiment" is the most complicated part. See the "Promo click (Goal ID 4 / Goal Set 1)" for an example.
In step 2 add as many variants as you plan to test. The urls are not important since we aren't using their js library to choose the variants. The name will show up in the report so choose good ones. "Original page" becomes variant 0 and each variant increments by one. We'll use the numbers in our `app/experiments.js` code.
Step 3 contains some script that we'll ignore. The important thing here is the **Experiment ID**. This is the value we need to name our experiment in `app/experiments.js`. Save the changes so far and wait until the code containing the experiment has been deployed to production **before** starting the experiment.
## Experiment code
Code for experiments live in [app/experiments.js](../app/experiments.js). There's an `experiments` object that contains the logic for deciding whether an experiment should run, which variant to use, and what to do. Each object needs to have these functions:
### `eligible` function
This function returns a boolean of whether this experiment should be active for this session. Any data available to the page can be used determine the result.
### `variant` function
This function returns which experimental group this session is placed in. The variant values need to match the values set up in Google Analytics, usually 0 thru N-1. This value is usually picked at random based on what percentage of each variant is desired.
### `run` function
This function gets the `variant` value chosen by the variant function and the `state` and `emitter` objects from the app. This function can do anything needed to change the app based on the experiment. A common pattern is to set or change a value on `state` that will be picked up by other parts of the app, like ui templates, to change how it looks or behaves.
### Example
Here's a full example of the experiment object:
```js
const experiments = {
S9wqVl2SQ4ab2yZtqDI3Dw: { // The Experiment ID from Google Analytics
id: 'S9wqVl2SQ4ab2yZtqDI3Dw',
run: function(variant, state, emitter) {
switch (variant) {
case 1:
state.promo = 'blue';
break;
case 2:
state.promo = 'pink';
break;
default:
state.promo = 'grey';
}
emitter.emit('render');
},
eligible: function() {
return (
!/firefox|fxios/i.test(navigator.userAgent) &&
document.querySelector('html').lang === 'en-US'
);
},
variant: function(state) {
const n = this.luckyNumber(state);
if (n < 0.33) {
return 0;
}
return n < 0.66 ? 1 : 2;
},
luckyNumber: function(state) {
return luckyNumber(
`${this.id}:${state.storage.get('testpilot_ga__cid')}`
);
}
}
};
```
## Reporting results
All metrics pings will include the variant and experiment id, but it's usually important to trigger a specific event to be counted as the experiment goal (the "Objective for this experiment" part from setup). Use an 'experiment' event to do this. For example:
```js
emit('experiment', { cd3: 'promo' });
```
where `emit` is the app emitter function passed to the [route handler](https://github.com/choojs/choo#approuteroutename-handlerstate-emit)
The second argument can be an object with any additional parameters. It usually includes a custom dimension that we chose to filter on while creating the experiment in Google Analytics.

View File

@@ -31,12 +31,11 @@ Since Send is an open source project, you can see all of the cool ways we use Ja
## How long are files available for?
Files are available to be downloaded for 24 hours, after which they are removed
from the server. They are also removed immediately after a download completes.
from the server. They are also removed immediately once the download limit is reached.
## Can a file be downloaded more than once?
Not currently, but we're considering multiple download support in a future
release.
Yes, once a file is submitted to Send you can select the download limit.
*Disclaimer: Send is an experiment and under active development. The answers

29
docs/localization.md Normal file
View File

@@ -0,0 +1,29 @@
# Localization
Send is localized in over 50 languages. We use the [fluent](http://projectfluent.org/) library and store our translations in [FTL](http://projectfluent.org/fluent/guide/) files in `public/locales/`. `en-US` is our base language, and other languages are managed by [pontoon](https://pontoon.mozilla.org/projects/test-pilot-firefox-send/).
## Process
Strings are added or removed from [public/locales/en-US/send.ftl] as needed. Strings **MUST NOT** be *changed* after they've been commited and pushed to master. Changing a string requires creating a new ID with a new name (preferably descriptive instead of incremented) and deletion of the obsolete ID. It's often useful to add a comment above the string with info about how and where the string is used.
Once new strings are commited to master they are available for translators in Pontoon. All languages other than `en-US` should be edited via Pontoon. Translations get automatically commited to the github master branch.
### Activation
The development environment includes all locales in `public/locales` via the `L10N_DEV` environment variable. Production uses `package.json` as the list of locales to use. Once a locale has enough string coverage it should be added to `package.json`.
## Code
In `app/` we use the `state.translate()` function to translate strings to the best matching language base on the user's `Accept-Language` header. It's a wrapper around fluent's [MessageContext.format](http://projectfluent.org/fluent.js/fluent/MessageContext.html). It works the same for both server and client side rendering.
### Examples
```js
// simple string
const finishedString = state.translate('downloadFinish')
// with parameters
const progressString = state.translate('downloadingPageProgress', {
filename: state.fileInfo.name,
size: bytes(state.fileInfo.size)
})
```

324
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "firefox-send",
"version": "2.4.1",
"version": "2.5.4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -417,6 +417,12 @@
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
"dev": true
},
"asmcrypto.js": {
"version": "0.22.0",
"resolved": "https://registry.npmjs.org/asmcrypto.js/-/asmcrypto.js-0.22.0.tgz",
"integrity": "sha512-usgMoyXjMbx/ZPdzTSXExhMPur2FTdz/Vo5PVx2gIaBcdAAJNOFlsdgqveM8Cff7W0v+xrf9BwjOV26JSAF9qA==",
"dev": true
},
"asn1": {
"version": "0.1.11",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz",
@@ -521,9 +527,9 @@
}
},
"aws-sdk": {
"version": "2.202.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.202.0.tgz",
"integrity": "sha1-wb2QwdwL/oNVIv6B8pz4u3G/AMw=",
"version": "2.206.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.206.0.tgz",
"integrity": "sha1-I1yhCVdsiI8kZ9HBDDOvfjQtO+E=",
"requires": {
"buffer": "4.9.1",
"events": "1.1.1",
@@ -769,9 +775,9 @@
}
},
"babel-loader": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.3.tgz",
"integrity": "sha512-PeN29YvOynPMvNk7QCzsHqxpmfXwKAC+uxkiSNFQsmXBBVltzEkVWmv/Ip3tx7yk149dQUwk497bTXNu+DZjLA==",
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.4.tgz",
"integrity": "sha512-/hbyEvPzBJuGpk9o80R0ZyTej6heEOr59GoEUtn8qFKbnx4cJm9FWES6J/iv644sYgrtVw9JJQkjaLW/bqb5gw==",
"dev": true,
"requires": {
"find-cache-dir": "1.0.0",
@@ -1442,9 +1448,9 @@
}
},
"bel": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/bel/-/bel-5.1.6.tgz",
"integrity": "sha512-qEjYYQgbMFbBwtrt+gVBk+IzdBNqyCgWjm7jtBqptcFlwaXRG/HgyHuzUucReYy155TB9UvIeF4P6/J2GpX80A==",
"version": "5.1.7",
"resolved": "https://registry.npmjs.org/bel/-/bel-5.1.7.tgz",
"integrity": "sha512-f3aAzoq2ilK3ErDsv47uo2qK9NTKHkguI7j6sJi6ynKS9vPG180QGU8BzHas6xPnIsKj+m7YXlDSm9BmaZHNrg==",
"requires": {
"hyperx": "2.3.3",
"is-electron": "2.1.0",
@@ -1617,9 +1623,9 @@
}
},
"browser-stdout": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
"integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
"dev": true
},
"browserify-aes": {
@@ -2002,11 +2008,11 @@
}
},
"choo": {
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/choo/-/choo-6.8.0.tgz",
"integrity": "sha512-yQkUqeqNtHdSeRik4yjPYIC0JRghdvG0AXxGGkqEgLqqOTCVVK8Fnu/x5FKOQ+CEGfodxIrWLIEHpx1AotmCGg==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/choo/-/choo-6.10.0.tgz",
"integrity": "sha512-5dSzBXh1PeyzKgzTTVMiIyO+2J/THwft/O65WDBnmMwwM2AveM2iDrHMcdzMm1Pr4U+44+hqAprBJbPigPYy5Q==",
"requires": {
"bel": "5.1.6",
"bel": "5.1.7",
"document-ready": "2.0.1",
"nanobus": "4.3.3",
"nanohref": "3.0.1",
@@ -2601,33 +2607,19 @@
"dev": true
},
"copy-webpack-plugin": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.4.2.tgz",
"integrity": "sha512-tf1XKKQ5h+BPvXJ5/zx2xKVdF0/6J8XNvhB6fdmIReMnAfQGMbzph8F7ok2QF9kqWMfIgkCxwzk1zXkYqcLIqg==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.5.0.tgz",
"integrity": "sha512-ROQ85fWKuhJfUkBTdHvfV+Zv6Ltm3G/vPVFdLPFwzWzd9RUY1yLw3rt6FmKK2PaeNQCNvmwgFhuarkjuV4PVDQ==",
"dev": true,
"requires": {
"cacache": "10.0.4",
"find-cache-dir": "1.0.0",
"globby": "7.1.1",
"is-glob": "4.0.0",
"loader-utils": "0.2.17",
"loader-utils": "1.1.0",
"minimatch": "3.0.4",
"p-limit": "1.2.0",
"serialize-javascript": "1.4.0"
},
"dependencies": {
"loader-utils": {
"version": "0.2.17",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
"integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
"dev": true,
"requires": {
"big.js": "3.2.0",
"emojis-list": "2.1.0",
"json5": "0.5.1",
"object-assign": "4.1.1"
}
}
}
},
"core-js": {
@@ -3658,21 +3650,21 @@
}
},
"duplexify": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.3.tgz",
"integrity": "sha512-g8ID9OroF9hKt2POf8YLayy+9594PzmM3scI00/uBXocX3TWNgoB67hjzkFe9ITAbQOne/lLdBxHXvYUM4ZgGA==",
"version": "3.5.4",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz",
"integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==",
"dev": true,
"requires": {
"end-of-stream": "1.4.1",
"inherits": "2.0.3",
"readable-stream": "2.3.4",
"readable-stream": "2.3.5",
"stream-shift": "1.0.0"
},
"dependencies": {
"readable-stream": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
"integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==",
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz",
"integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==",
"dev": true,
"requires": {
"core-util-is": "1.0.2",
@@ -3956,21 +3948,21 @@
}
},
"eslint": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.1.tgz",
"integrity": "sha512-gPSfpSRCHre1GLxGmO68tZNxOlL2y7xBd95VcLD+Eo4S2js31YoMum3CAQIOaxY24hqYOMksMvW38xuuWKQTgw==",
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.2.tgz",
"integrity": "sha512-qy4i3wODqKMYfz9LUI8N2qYDkHkoieTbiHpMrYUI/WbjhXJQr7lI4VngixTgaG+yHX+NBCv7nW4hA0ShbvaNKw==",
"dev": true,
"requires": {
"ajv": "5.5.2",
"babel-code-frame": "6.26.0",
"chalk": "2.3.1",
"chalk": "2.3.2",
"concat-stream": "1.6.0",
"cross-spawn": "5.1.0",
"debug": "3.1.0",
"doctrine": "2.1.0",
"eslint-scope": "3.7.1",
"eslint-visitor-keys": "1.0.0",
"espree": "3.5.3",
"espree": "3.5.4",
"esquery": "1.0.0",
"esutils": "2.0.2",
"file-entry-cache": "2.0.0",
@@ -3981,7 +3973,7 @@
"imurmurhash": "0.1.4",
"inquirer": "3.3.0",
"is-resolvable": "1.1.0",
"js-yaml": "3.10.0",
"js-yaml": "3.11.0",
"json-stable-stringify-without-jsonify": "1.0.1",
"levn": "0.3.0",
"lodash": "4.17.5",
@@ -3996,10 +3988,16 @@
"semver": "5.5.0",
"strip-ansi": "4.0.0",
"strip-json-comments": "2.0.1",
"table": "4.0.3",
"table": "4.0.2",
"text-table": "0.2.0"
},
"dependencies": {
"ajv-keywords": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
"integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
"dev": true
},
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
@@ -4007,23 +4005,23 @@
"dev": true
},
"ansi-styles": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
"integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "1.9.1"
}
},
"chalk": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz",
"integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==",
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
"integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==",
"dev": true,
"requires": {
"ansi-styles": "3.2.0",
"ansi-styles": "3.2.1",
"escape-string-regexp": "1.0.5",
"supports-color": "5.2.0"
"supports-color": "5.3.0"
}
},
"debug": {
@@ -4054,9 +4052,9 @@
"dev": true
},
"js-yaml": {
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
"integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz",
"integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
"dev": true,
"requires": {
"argparse": "1.0.10",
@@ -4073,23 +4071,37 @@
}
},
"supports-color": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz",
"integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==",
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
"integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
"dev": true,
"requires": {
"has-flag": "3.0.0"
}
},
"table": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
"integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
"dev": true,
"requires": {
"ajv": "5.5.2",
"ajv-keywords": "2.1.1",
"chalk": "2.3.2",
"lodash": "4.17.5",
"slice-ansi": "1.0.0",
"string-width": "2.1.1"
}
}
}
},
"eslint-plugin-mocha": {
"version": "4.11.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-4.11.0.tgz",
"integrity": "sha1-kRk6L1XiCl41l0BUoAidMBmO5Xg=",
"version": "4.12.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-4.12.1.tgz",
"integrity": "sha512-hxWtYHvLA0p/PKymRfDYh9Mxt5dYkg2Goy1vZDarTEEYfELP9ksga7kKG1NUKSQy27C8Qjc7YrSWTLUhOEOksA==",
"dev": true,
"requires": {
"ramda": "0.24.1"
"ramda": "0.25.0"
}
},
"eslint-plugin-node": {
@@ -4130,13 +4142,21 @@
"dev": true
},
"espree": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/espree/-/espree-3.5.3.tgz",
"integrity": "sha512-Zy3tAJDORxQZLl2baguiRU1syPERAIg0L+JB2MWorORgTu/CplzvxS9WWA7Xh4+Q+eOQihNs/1o1Xep8cvCxWQ==",
"version": "3.5.4",
"resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
"integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
"dev": true,
"requires": {
"acorn": "5.4.1",
"acorn": "5.5.3",
"acorn-jsx": "3.0.1"
},
"dependencies": {
"acorn": {
"version": "5.5.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz",
"integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==",
"dev": true
}
}
},
"esprima": {
@@ -4501,6 +4521,12 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
"fast-text-encoding": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.0.tgz",
"integrity": "sha512-R9bHCvweUxxwkDwhjav5vxpFvdPGlVngtqmx4pIZfSUhM/Q4NiIUHB456BAf+Q1Nwu3HEZYONtu+Rya+af4jiQ==",
"dev": true
},
"fastparse": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
@@ -4545,9 +4571,9 @@
}
},
"file-loader": {
"version": "1.1.9",
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.9.tgz",
"integrity": "sha512-6ql03hOSoJHBkTB+3De/f7NJse+JXkUwvAf3y4Q5rIcTD0kqJiE3btvLnDcZT+P4t1QYLb9dJ9EI4auzfo3wFA==",
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz",
"integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==",
"dev": true,
"requires": {
"loader-utils": "1.1.0",
@@ -4555,9 +4581,9 @@
},
"dependencies": {
"ajv": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.1.1.tgz",
"integrity": "sha1-l41Zf7wrfQ5aXD3esUmmgvKr+g4=",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.1.tgz",
"integrity": "sha1-KKarxJOiq+D7TIUHrK7bQ/pVBnE=",
"dev": true,
"requires": {
"fast-deep-equal": "1.0.0",
@@ -4571,7 +4597,7 @@
"integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==",
"dev": true,
"requires": {
"ajv": "6.1.1",
"ajv": "6.2.1",
"ajv-keywords": "3.1.0"
}
}
@@ -4705,13 +4731,13 @@
"dev": true,
"requires": {
"inherits": "2.0.3",
"readable-stream": "2.3.4"
"readable-stream": "2.3.5"
},
"dependencies": {
"readable-stream": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
"integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==",
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz",
"integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==",
"dev": true,
"requires": {
"core-util-is": "1.0.2",
@@ -4823,13 +4849,13 @@
"dev": true,
"requires": {
"inherits": "2.0.3",
"readable-stream": "2.3.4"
"readable-stream": "2.3.5"
},
"dependencies": {
"readable-stream": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
"integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==",
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz",
"integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==",
"dev": true,
"requires": {
"core-util-is": "1.0.2",
@@ -6209,9 +6235,9 @@
"dev": true
},
"helmet": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-3.11.0.tgz",
"integrity": "sha512-Xqf6VXmjpZoyH4reGyeBCO5nHH0NVeRQnx23LFj6AK9ocPRgZJfSH6zZ8SvNO2tB+fKhsqy1RSjIjWHVvH1X+w==",
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-3.12.0.tgz",
"integrity": "sha512-CgkctpvreQLL6X3EL2Igs/92+75ZFIsrob9/Rdwf2hQCBGH/DxLk4xFPxAAl6jYnnus/YXfFEVXHEJf8TJTwlA==",
"requires": {
"dns-prefetch-control": "0.1.0",
"dont-sniff-mimetype": "1.0.0",
@@ -6224,7 +6250,7 @@
"ienoopen": "1.0.0",
"nocache": "2.0.0",
"referrer-policy": "1.1.0",
"x-xss-protection": "1.0.0"
"x-xss-protection": "1.1.0"
}
},
"helmet-csp": {
@@ -9647,7 +9673,7 @@
"dev": true,
"requires": {
"concat-stream": "1.6.0",
"duplexify": "3.5.3",
"duplexify": "3.5.4",
"end-of-stream": "1.4.1",
"flush-write-stream": "1.0.2",
"from2": "2.3.0",
@@ -9688,15 +9714,15 @@
}
},
"mocha": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.1.tgz",
"integrity": "sha512-SpwyojlnE/WRBNGtvJSNfllfm5PqEDFxcWluSIgLeSBJtXG4DmoX2NNAeEA7rP5kK+79VgtVq8nG6HskaL1ykg==",
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.4.tgz",
"integrity": "sha512-nMOpAPFosU1B4Ix1jdhx5e3q7XO55ic5a8cgYvW27CequcEY+BabS0kUVL1Cw1V5PuVHZWeNRWFLmEPexo79VA==",
"dev": true,
"requires": {
"browser-stdout": "1.3.0",
"browser-stdout": "1.3.1",
"commander": "2.11.0",
"debug": "3.1.0",
"diff": "3.3.1",
"diff": "3.5.0",
"escape-string-regexp": "1.0.5",
"glob": "7.1.2",
"growl": "1.10.3",
@@ -9720,6 +9746,12 @@
"ms": "2.0.0"
}
},
"diff": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
"dev": true
},
"has-flag": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
@@ -12305,13 +12337,13 @@
"requires": {
"cyclist": "0.2.2",
"inherits": "2.0.3",
"readable-stream": "2.3.4"
"readable-stream": "2.3.5"
},
"dependencies": {
"readable-stream": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
"integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==",
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz",
"integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==",
"dev": true,
"requires": {
"core-util-is": "1.0.2",
@@ -14389,21 +14421,21 @@
}
},
"postcss-loader": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.0.tgz",
"integrity": "sha512-S/dKzpDwGFmP9g8eyCu9sUIV+/+3UooeTpYlsKf23qKDdrhHuA4pTSfytVu0rEJ0iDqUavXrgtOPq5KhNyNMOw==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.1.tgz",
"integrity": "sha512-f0J/DWE/hyO9/LH0WHpXkny/ZZ238sSaG3p1SRBtVZnFWUtD7GXIEgHoBg8cnAeRbmEvUxHQptY46zWfwNYj/w==",
"dev": true,
"requires": {
"loader-utils": "1.1.0",
"postcss": "6.0.18",
"postcss": "6.0.19",
"postcss-load-config": "1.2.0",
"schema-utils": "0.4.5"
},
"dependencies": {
"ajv": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.1.1.tgz",
"integrity": "sha1-l41Zf7wrfQ5aXD3esUmmgvKr+g4=",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.1.tgz",
"integrity": "sha1-KKarxJOiq+D7TIUHrK7bQ/pVBnE=",
"dev": true,
"requires": {
"fast-deep-equal": "1.0.0",
@@ -14411,30 +14443,24 @@
"json-schema-traverse": "0.3.1"
}
},
"ajv-keywords": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz",
"integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=",
"dev": true
},
"ansi-styles": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
"integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "1.9.1"
}
},
"chalk": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz",
"integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==",
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
"integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==",
"dev": true,
"requires": {
"ansi-styles": "3.2.0",
"ansi-styles": "3.2.1",
"escape-string-regexp": "1.0.5",
"supports-color": "5.2.0"
"supports-color": "5.3.0"
}
},
"has-flag": {
@@ -14444,14 +14470,14 @@
"dev": true
},
"postcss": {
"version": "6.0.18",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.18.tgz",
"integrity": "sha512-X8MyLi3OYI1o71u0SsefWLpGBo5xnGiK1Pn+nrZFplc671Ts7L8aPwEbPIO8AWpulK5wuaVzyM9Rw6R8o7hYBw==",
"version": "6.0.19",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz",
"integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==",
"dev": true,
"requires": {
"chalk": "2.3.1",
"chalk": "2.3.2",
"source-map": "0.6.1",
"supports-color": "5.2.0"
"supports-color": "5.3.0"
}
},
"schema-utils": {
@@ -14460,7 +14486,7 @@
"integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==",
"dev": true,
"requires": {
"ajv": "6.1.1",
"ajv": "6.2.1",
"ajv-keywords": "3.1.0"
}
},
@@ -14471,9 +14497,9 @@
"dev": true
},
"supports-color": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz",
"integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==",
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
"integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
"dev": true,
"requires": {
"has-flag": "3.0.0"
@@ -15723,9 +15749,9 @@
"dev": true
},
"prettier": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.10.2.tgz",
"integrity": "sha512-TcdNoQIWFoHblurqqU6d1ysopjq7UX0oRcT/hJ8qvBAELiYWn+Ugf0AXdnzISEJ7vuhNnQ98N8jR8Sh53x4IZg==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.11.1.tgz",
"integrity": "sha512-T/KD65Ot0PB97xTrG8afQ46x3oiVhnfGjGESSI9NWYcG92+OUPZKkwHqGWXH2t9jK1crnQjubECW0FuOth+hxw==",
"dev": true
},
"pretty-format": {
@@ -15869,7 +15895,7 @@
"integrity": "sha512-2kmNR9ry+Pf45opRVirpNuIFotsxUGLaYqxIwuR77AYrYRMuFCz9eryHBS52L360O+NcR383CL4QYlMKPq4zYA==",
"dev": true,
"requires": {
"duplexify": "3.5.3",
"duplexify": "3.5.4",
"inherits": "2.0.3",
"pump": "2.0.1"
}
@@ -15940,9 +15966,9 @@
"dev": true
},
"ramda": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz",
"integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc=",
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz",
"integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==",
"dev": true
},
"randomatic": {
@@ -16011,9 +16037,9 @@
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
},
"raven": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/raven/-/raven-2.4.1.tgz",
"integrity": "sha512-LLLS8bOJC1q33qszBsLaEtEg7X8G8hYLGcKO4s6EifAce2BN6cTRdBXNvwVNv4kNk82YUZYrj53yEbL4kCmjjw==",
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/raven/-/raven-2.4.2.tgz",
"integrity": "sha1-ASnircMHiGRv1TC2fQioziXU9tw=",
"requires": {
"cookie": "0.3.1",
"md5": "2.2.1",
@@ -16035,9 +16061,9 @@
}
},
"raven-js": {
"version": "3.22.3",
"resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.22.3.tgz",
"integrity": "sha512-pIzHpAggyTOGJE3ruAKdZNK5qhO4V21kR7lwpdUM875yHpq1cqeGzvs78/RufF3g7NaAvVmMPCbaV9uUhQzJ3A==",
"version": "3.23.1",
"resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.23.1.tgz",
"integrity": "sha512-cfkGRgz1TkFmEM5ahPWkIEav2+3zr32qMaBvKizzxN7fZapLbCrxMHMLDn7LSVGN0+dyPKY18imv3i0dkLRoKg==",
"dev": true
},
"raw-body": {
@@ -17963,9 +17989,9 @@
"dev": true
},
"stylelint-config-standard": {
"version": "18.1.0",
"resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-18.1.0.tgz",
"integrity": "sha512-kjpxnt1fu56ZJk+8wETz0Hr/3vvpj5KfQoBRLVeAJcFtCZBxF5kUDXGqsn4h2ZVyvNTf+2lOfX1dfok5ZOltqg==",
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-18.2.0.tgz",
"integrity": "sha512-07x0TaSIzvXlbOioUU4ORkCIM07kyIuojkbSVCyFWNVgXMXYHfhnQSCkqu+oHWJf3YADAnPGWzdJ53NxkoJ7RA==",
"dev": true,
"requires": {
"stylelint-config-recommended": "2.1.0"
@@ -19946,9 +19972,9 @@
"dev": true
},
"x-xss-protection": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.0.0.tgz",
"integrity": "sha1-iYr7k4abJGYc+cUvnujbjtB2Tdk="
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.1.0.tgz",
"integrity": "sha512-rx3GzJlgEeZ08MIcDsU2vY2B1QEriUKJTSiNHHUIem6eg9pzVOr2TL3Y4Pd6TMAM5D5azGjcxqI62piITBDHVg=="
},
"xml-char-classes": {
"version": "1.0.0",

View File

@@ -1,7 +1,7 @@
{
"name": "firefox-send",
"description": "File Sharing Experiment",
"version": "2.4.1",
"version": "2.5.4",
"author": "Mozilla (https://mozilla.org)",
"repository": "mozilla/send",
"homepage": "https://github.com/mozilla/send/",
@@ -26,11 +26,12 @@
"contributors": "git shortlog -s | awk -F\\t '{print $2}' > CONTRIBUTORS",
"release": "npm-run-all contributors changelog",
"test": "npm-run-all test:*",
"test:backend": "nyc mocha --reporter=min test/unit",
"test:backend": "nyc mocha --reporter=min test/backend",
"test:frontend": "cross-env NODE_ENV=development node test/frontend/runner.js && nyc report --reporter=html",
"start": "cross-env NODE_ENV=development webpack-dev-server",
"prod": "node server/prod.js",
"cover": "nyc --reporter=html mocha test/unit"
"test-integration": "docker-compose up --abort-on-container-exit --exit-code-from integration-tests --build --remove-orphans --quiet-pull && docker-compose down",
"test-integration-stage": "cross-env BASE_URL=https://send.stage.mozaws.net npm run test-integration",
"start": "npm run clean && cross-env NODE_ENV=development webpack-dev-server",
"prod": "node server/prod.js"
},
"lint-staged": {
"*.js": [
@@ -54,8 +55,9 @@
"node": ">=8.2.0"
},
"devDependencies": {
"asmcrypto.js": "^0.22.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.3",
"babel-loader": "^7.1.4",
"babel-plugin-istanbul": "^4.1.5",
"babel-plugin-yo-yoify": "^1.0.2",
"babel-preset-env": "^1.6.1",
@@ -63,25 +65,26 @@
"babel-preset-stage-2": "^6.24.1",
"babel-preset-stage-3": "^6.24.1",
"base64-js": "^1.2.3",
"copy-webpack-plugin": "^4.4.2",
"copy-webpack-plugin": "^4.5.0",
"cross-env": "^5.1.3",
"css-loader": "^0.28.10",
"css-mqpacker": "^6.0.2",
"eslint": "^4.18.1",
"eslint-plugin-mocha": "^4.11.0",
"eslint": "^4.18.2",
"eslint-plugin-mocha": "^4.12.1",
"eslint-plugin-node": "^6.0.1",
"eslint-plugin-security": "^1.4.0",
"expose-loader": "^0.7.4",
"extract-loader": "^1.0.2",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.9",
"fast-text-encoding": "^1.0.0",
"file-loader": "^1.1.11",
"fluent-intl-polyfill": "^0.1.0",
"git-rev-sync": "^1.10.0",
"github-changes": "^1.1.2",
"html-loader": "^0.5.5",
"husky": "^0.14.3",
"lint-staged": "^7.0.0",
"mocha": "^5.0.0",
"mocha": "^5.0.4",
"nanobus": "^4.3.2",
"nanotiming": "^7.3.0",
"npm-run-all": "^4.1.2",
@@ -89,18 +92,18 @@
"nyc": "^11.5.0",
"postcss-cssnext": "^3.1.0",
"postcss-import": "^11.1.0",
"postcss-loader": "^2.1.0",
"prettier": "^1.10.2",
"postcss-loader": "^2.1.1",
"prettier": "^1.11.1",
"proxyquire": "^1.8.0",
"puppeteer": "^1.1.1",
"raven-js": "^3.22.2",
"raven-js": "^3.23.1",
"redis-mock": "^0.21.0",
"require-from-string": "^2.0.1",
"rimraf": "^2.6.2",
"sinon": "^4.4.2",
"string-hash": "^1.1.3",
"stylelint": "^9.1.1",
"stylelint-config-standard": "^18.1.0",
"stylelint-config-standard": "^18.2.0",
"stylelint-no-unsupported-browser-features": "^2.0.0",
"svgo": "^1.0.5",
"svgo-loader": "^2.1.0",
@@ -113,19 +116,19 @@
"webpack-unassert-loader": "^1.2.0"
},
"dependencies": {
"aws-sdk": "^2.202.0",
"aws-sdk": "^2.206.0",
"babel-polyfill": "^6.26.0",
"choo": "^6.7.0",
"choo": "^6.10.0",
"cldr-core": "^32.0.0",
"connect-busboy": "0.0.2",
"convict": "^4.0.1",
"express": "^4.16.2",
"fluent": "^0.6.3",
"fluent-langneg": "^0.1.0",
"helmet": "^3.11.0",
"helmet": "^3.12.0",
"mkdirp": "^0.5.1",
"mozlog": "^2.2.0",
"raven": "^2.4.1",
"raven": "^2.4.2",
"redis": "^2.8.0"
},
"availableLanguages": [
@@ -138,6 +141,7 @@
"cak",
"cs",
"cy",
"da",
"de",
"dsb",
"el",
@@ -171,6 +175,7 @@
"sq",
"sr",
"sv-SE",
"te",
"tl",
"tr",
"uk",

View File

@@ -29,7 +29,8 @@ uploadSvgAlt =
.alt = ارفع
uploadSuccessTimingHeader = ستنتهي صلاحية الرابط الذي يشير إلى الملف في حال: نُزِّل لأول مرة، أو مرّ ٢٤ ساعة على رفعه.
expireInfo = ستنتهي صلاحية رابط الملف بعد { $downloadCount } أو { $timespan }.
downloadCount = { $num ->
downloadCount =
{ $num ->
[zero] لا تنزيلات
[one] تنزيل واحد
[two] تنزيلين
@@ -37,7 +38,8 @@ downloadCount = { $num ->
[many] { $num } تنزيلًا
*[other] { $num } تنزيل
}
timespanHours = { $num ->
timespanHours =
{ $num ->
[zero] أقل من ساعة
[one] ساعة
[two] ساعتين
@@ -122,8 +124,6 @@ requirePasswordCheckbox = اطلب كلمة سر لتنزيل هذا الملف
addPasswordButton = أضِف كلمة سر
changePasswordButton = غيّر
passwordTryAgain = كلمة السر خاطئة. أعِد المحاولة.
# This label is followed by the password needed to download a file
passwordResult = كلمة السر: { $password }
reportIPInfringement = أبلغ عن انتهاك للملكية الفكرية
javascriptRequired = يتطلب فَيَرفُكس سِنْد جافاسكربت
whyJavascript = لماذا يتطلب فَيَرفُكس سِنْد جافاسكربت؟
@@ -134,3 +134,7 @@ expiresHoursMinutes = { $hours }س { $minutes }د
expiresMinutes = { $minutes }د
# A short status message shown when a password is successfully set
passwordIsSet = ضُبطت كلمة السر
# A short status message shown when the user enters a long password
maxPasswordLength = أقصر طول لكلمة السر: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = يجب ألا تُضبط كلمة السر هذه

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = esperimentu web
siteFeedback = Feedback
@@ -25,28 +25,41 @@ uploadingFileNotification = Avísame cuando se complete la xuba.
uploadSuccessConfirmHeader = Preparáu pa unviar
uploadSvgAlt = Xubir
uploadSuccessTimingHeader = L'enllaz del to ficheru caducará dempués d'una descarga o en 24 hores.
downloadCount =
{ $num ->
[one] 1 descarga
*[other] { $num } descargues
}
timespanHours =
{ $num ->
[one] 1 hora
*[other] { $num } hores
}
copyUrlFormLabelWithName = Copia y comparti l'enllaz pa unviar el to ficheru: { $filename }
copyUrlFormButton = Copiar al cartafueyu
copiedUrl = ¡Copióse!
deleteFileButton = Desaniciar ficheru
sendAnotherFileLink = Unviar otru ficheru
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = Baxar
downloadsFileList = Descargues
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = Baxar { $filename }
downloadFileSize = ({ $size })
unlockInputLabel = Introducir contraseña
unlockInputPlaceholder = Contraseña
unlockButtonLabel = Desbloquiar
downloadFileTitle = Baxar ficheru cifráu
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
downloadMessage = El to collaciu unvióte un ficheru usando Firefox Send, un serviciu que te permite compartir ficheros con un enllaz seguru, priváu y cifráu que caduca automáticamente p'asegurar que les to coses nun queden siempres na rede.
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Baxar
downloadNotification = Completóse la to descarga.
downloadFinish = Descarga completada
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } de { $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Prueba Firefox Send
downloadingPageProgress = Baxando { $filename } ({ $size })
downloadingPageMessage = Dexa esta llingüeta abierta entrín vamos en cata del to ficheru y lu desciframos, por favor.
@@ -58,7 +71,7 @@ fileTooBig = Esti ficheru ye mui grande como pa xubilu. Debería tener menos de
linkExpiredAlt = Enllaz caducáu
expiredPageHeader = ¡Esti enllaz caducó o enxamás nun esistó!
notSupportedHeader = El to restolador nun ta sofitáu.
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = Desafortunadamente esti restolador nun sofita la teunoloxía web qu'usa Firefox Send. Precisarás d'usar otru restolador. ¡Aconseyámoste Firefox!
notSupportedLink = ¿Por qué'l mio restolador nun ta sofitáu?
notSupportedOutdatedDetail = Desafortunadamente esta versión de Firefox nun sofita la teunoloxía web qu'usa Firefox Send. Precisarás d'anovar Firefox.
@@ -66,7 +79,7 @@ updateFirefox = Anovar Firefox
downloadFirefoxButtonSub = Descarga de baldre
uploadedFile = Ficheru
copyFileList = Copiar URL
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = Caduca en
deleteFileList = Desaniciar
nevermindButton = Nun m'importa
@@ -79,13 +92,14 @@ deletePopupCancel = Encaboxar
deleteButtonHover = Desaniciar
copyUrlHover = Copiar URL
footerLinkLegal = Llegal
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Tocante a Test Pilot
footerLinkPrivacy = Privacidá
footerLinkTerms = Términos
footerLinkCookies = Cookies
requirePasswordCheckbox = Riquir una contraseña pa baxar esti ficheru
addPasswordButton = Amestar contraseña
changePasswordButton = Camudar
passwordTryAgain = Contraseña incorreuta. Volvi tentalo.
// This label is followed by the password needed to download a file
passwordResult = Contraseña: { $password }
# A short status message shown when there was an error setting the password
passwordSetError = Nun pudo afitase esta contraseña

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = web eksperiment
siteFeedback = Geri dönüş
@@ -39,29 +39,29 @@ copyUrlFormButton = Buferə köçür
copiedUrl = Köçürüldü!
deleteFileButton = Faylı sil
sendAnotherFileLink = Başqa fayl göndər
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = Endir
downloadsFileList = Endirmələr
// Used as header in a column indicating the amount of time left before a
// download link expires (e.g. "10h 5m")
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = Vaxt
// Used as header in a column indicating the number of times a file has been
// downloaded
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = { $filename } faylını endir
downloadFileSize = ({ $size })
unlockInputLabel = Parol daxil edin
unlockInputPlaceholder = Parol
unlockButtonLabel = Aç
downloadFileTitle = Şifrələnmiş Faylı Endir
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
downloadMessage = Yoldaşınız Firefox Send ilə sizə fayl göndərir, fayllarınızı təhlükəsiz, məxfi, şifrələnmiş və daima onlayn qalmaması üçün avtomatik silən fayl göndərmə xidməti.
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Endir
downloadNotification = Endirməniz tamamlandı.
downloadFinish = Endirmə Tamamlandı
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } / { $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Firefox Send Yoxla
downloadingPageProgress = { $filename } faylı ({ $size }) endirilir
downloadingPageMessage = Lütfən faylı endirib şifrəsini açarkən vərəqi açıq buraxın.
@@ -73,7 +73,7 @@ fileTooBig = Fayl yükləmək üçün çox böyükdür. Fayl { $size }-dan az ol
linkExpiredAlt = Keçidin vaxtı çıxıb
expiredPageHeader = Keçidin vaxtı çıxıb və ya heç vaxt olmayıb!
notSupportedHeader = Səyyahınız dəstəklənmir.
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = Heyf ki, bu səyyah Firefox Send-ə güc verən web texnologiyalarını dəstəkləmir. Fərqli bir səyyah yoxlamalısınız. Biz Firefox məsləhət görürük!
notSupportedLink = Səyyahım niyə dəstəklənmir?
notSupportedOutdatedDetail = Heyf ki, Firefox səyyahının bu versiyası Firefox Send-ə güc verən web texnologiyalarını dəstəkləmir. Səyyahınızı yeniləməlisiniz.
@@ -81,7 +81,7 @@ updateFirefox = Firefox-u Yenilə
downloadFirefoxButtonSub = Pulsuz Endir
uploadedFile = Fayl
copyFileList = Keçidi Köçürt
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = Vaxtı çıxma tarixi
deleteFileList = Sil
nevermindButton = Vacib deyil
@@ -94,7 +94,7 @@ deletePopupCancel = Ləğv et
deleteButtonHover = Sil
copyUrlHover = Keçidi Köçürt
footerLinkLegal = Hüquqi
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Test Pilot Haqqında
footerLinkPrivacy = Məxfilik
footerLinkTerms = Şərtlər
@@ -103,13 +103,17 @@ requirePasswordCheckbox = Bu faylı endirmək üçün parol tələb et
addPasswordButton = Parol əlavə et
changePasswordButton = Dəyişdir
passwordTryAgain = Səhv parol. Təkrar yoxlayın.
// This label is followed by the password needed to download a file
passwordResult = Parol: { $password }
reportIPInfringement = Əqli-mülkiyyət pozuntusu bildir
javascriptRequired = Firefox Send üçün JavaScript lazımdır
whyJavascript = Firefox Send niyə JavaScript tələb edir?
enableJavascript = Lütfən JavaScript-i aktiv edib təkrar yoxlayın.
// A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours } saat { $minutes } dəq
// A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes } dəq
# A short status message shown when a password is successfully set
passwordIsSet = Parol quruldu
# A short status message shown when the user enters a long password
maxPasswordLength = Maksimum parol uzunluğu: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = Parol qurula bilmədi

View File

@@ -26,11 +26,13 @@ uploadSuccessConfirmHeader = Llest per enviar
uploadSvgAlt = Puja
uploadSuccessTimingHeader = L'enllaç al fitxer caducarà quan es baixi una vegada o d'aquí 24 hores.
expireInfo = L'enllaç al fitxer caducarà en fer { $downloadCount } o d'aquí { $timespan }.
downloadCount = { $num ->
downloadCount =
{ $num ->
[one] 1 baixada
*[other] { $num } baixades
}
timespanHours = { $num ->
timespanHours =
{ $num ->
[one] 1 hora
*[other] { $num } hores
}
@@ -103,8 +105,6 @@ requirePasswordCheckbox = Sol·licita una contrasenya per baixar aquest fitxer
addPasswordButton = Afegeix una contrasenya
changePasswordButton = Canvia
passwordTryAgain = La contrasenya és incorrecta. Torneu-ho a provar.
# This label is followed by the password needed to download a file
passwordResult = Contrasenya: { $password }
reportIPInfringement = Denuncieu una infracció de propietat intel·lectual
javascriptRequired = El Firefox Send necessita JavaScript
whyJavascript = Per què el Firefox Send necessita JavaScript?
@@ -115,3 +115,7 @@ expiresHoursMinutes = { $hours } h { $minutes } min
expiresMinutes = { $minutes } min
# A short status message shown when a password is successfully set
passwordIsSet = S'ha definit la contrasenya
# A short status message shown when the user enters a long password
maxPasswordLength = Longitud màxima de la contrasenya: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = No s'ha pogut definir la contrasenya

View File

@@ -32,9 +32,9 @@ downloadCount = { $num ->
*[other] { $num } staženích
}
timespanHours = { $num ->
[one] hodina
[few] hodiny
*[other] hodin
[one] jedné hodině
[few] { $num } hodinách
*[other] { $num } hodinách
}
copyUrlFormLabelWithName = Zkopírujte a sdílejte odkaz na váš soubor: { $filename }
copyUrlFormButton = Zkopírovat do schránky
@@ -110,9 +110,9 @@ javascriptRequired = Firefox Send vyžaduje povolený JavaScript
whyJavascript = Proč Firefox Send vyžaduje povolený JavaScript?
enableJavascript = Povolte JavaScript a zkuste to znovu.
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours }h { $minutes }m
expiresHoursMinutes = { $hours } h { $minutes } m
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes }m
expiresMinutes = { $minutes } m
# A short status message shown when a password is successfully set
passwordIsSet = Heslo nastaveno
# A short status message shown when the user enters a long password

View File

@@ -26,16 +26,22 @@ uploadSuccessConfirmHeader = Yn Barod i Anfon
uploadSvgAlt = Llwytho i Fyny
uploadSuccessTimingHeader = Bydd y ddolen i'ch ffeil y dod i ben ar ôl 1 llwytho neu o fewn 24 awr.
expireInfo = Bydd y ddolen i'ch ffeil yn dod i ben ym mhen { $downloadCount } neu { $timespan }.
downloadCount = { $num ->
downloadCount =
{ $num ->
[zero] Llwythi i lawr
[one] Llwyth i lawr
[two] Lwyth i lawr
[few] Llwyth i lawr
[many] Llwyth i lawr
*[other] Llwyth i lawr
}
timespanHours = { $num ->
timespanHours =
{ $num ->
[zero] awr
[one] awr
[two] awr
[few] awr
[many] awr
*[other] awr
}
copyUrlFormLabelWithName = Copïo a rhannu'r ddolen i anfon eich ffeil: { $filename }

View File

@@ -0,0 +1,121 @@
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = webeksperiment
siteFeedback = Feedback
uploadPageHeader = Privat, krypteret fildeling
uploadPageExplainer = Send filer gennem et sikkert, privat og krypteret link, som automatisk udløber for at sikre, at dine ting ikke forbliver på nettet for altid.
uploadPageLearnMore = Læs mere
uploadPageDropMessage = Drop dine fil her for at begynde at uploade
uploadPageSizeMessage = For den mest pålidelige drift er det bedst at holde din fil under 1GB
uploadPageBrowseButton = Vælg en fil på din computer
uploadPageBrowseButton1 = Vælg en fil at uploade
uploadPageMultipleFilesAlert = Upload af flere filer eller en mappe understøttes ikke i øjeblikket.
uploadPageBrowseButtonTitle = Upload fil
uploadingPageProgress = Uploader { $filename } { $size }
importingFile = Importerer…
verifyingFile = Bekræfter…
encryptingFile = Krypterer…
decryptingFile = Dekrypterer…
notifyUploadDone = Din upload er færdig.
uploadingPageMessage = Når din fil er uploadet, kan du vælge udløbsindstillinger.
uploadingPageCancel = Annuller upload
uploadCancelNotification = Dit upload blev annulleret.
uploadingPageLargeFileMessage = Denne fil er stor, så det kan tage lang tid at uploade den. Vær tålmodig!
uploadingFileNotification = Giv mig besked, når filen er færdig.
uploadSuccessConfirmHeader = Klar til at sende
uploadSvgAlt = Upload
uploadSuccessTimingHeader = Linket til din fil udløber efter 1 hentning eller om 24 timer.
expireInfo = Linket til din fil udløber efter { $downloadCount } eller { $timespan }.
downloadCount =
{ $num ->
[one] 1 hentning
*[other] { $num } hentninger
}
timespanHours =
{ $num ->
[one] 1 time
*[other] { $num } timer
}
copyUrlFormLabelWithName = Kopier og del linket for at sende din fil: { $filename }
copyUrlFormButton = Kopier til udklipsholder
copiedUrl = Kopieret!
deleteFileButton = Slet fil
sendAnotherFileLink = Send endnu en fil
# Alternative text used on the download link/button (indicates an action).
downloadAltText = Hent
downloadsFileList = Hentninger
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = Tid
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = Hent { $filename }
downloadFileSize = ({ $size })
unlockInputLabel = Indtast adgangskode
unlockInputPlaceholder = Adgangskode
unlockButtonLabel = Lås op
downloadFileTitle = Hent krypteret fil
# Firefox Send is a brand name and should not be localized.
downloadMessage = Din ven sender dig en fil med Firefox Send, en tjeneste, der lader dig dele filer via et sikkert, privat og krypteret link, som automatisk udløber for at sikre, at dine ting ikke forbliver på nettet for altid.
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Hent
downloadNotification = Hentning af din fil er fuldført.
downloadFinish = Hentning fuldført
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } af { $totalSize })
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Prøv Firefox Send
downloadingPageProgress = Henter { $filename } { $size }
downloadingPageMessage = Hold dette faneblad åbent, mens vi henter og dekrypterer din fil.
errorAltText = Upload mislykkedes
errorPageHeader = Der gik noget galt!
errorPageMessage = Der opstod en fejl under upload af filen.
errorPageLink = Send endnu en fil
fileTooBig = Den fil er for stor at uploade. Den skal være mindre end { $size }.
linkExpiredAlt = Link er udløbet
expiredPageHeader = Dette link er udløbet eller har aldrig eksisteret!
notSupportedHeader = Din browser understøttes ikke.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = Desværre understøtter denne browser ikke den webteknologi, som driver Firefox Send. Du skal bruge en anden browser. Vi anbefaler Firefox!
notSupportedLink = Hvorfor understøttes min browser ikke?
notSupportedOutdatedDetail = Desværre understøtter denne version af Firefox ikke den webteknologi, som driver Firefox Send. Du skal opdatere din browser.
updateFirefox = Opdater Firefox
downloadFirefoxButtonSub = Gratis download
uploadedFile = Fil
copyFileList = Kopier URL
# expiryFileList is used as a column header
expiryFileList = Udløber om
deleteFileList = Slet
nevermindButton = Glem det
legalHeader = Betingelser & privatliv
legalNoticeTestPilot = Firefox Send er i øjeblikket et Testpilot-eksperiment, som er underlagt Testpilots <a>betingelser for brug</a> og <a>privatlivspolitik</a>. Du kan læse mere om eksperimentet og dets indsamling af data <a>her</a>.
legalNoticeMozilla = Brugen af webstedet Firefox Send er også underlagt Mozillas <a>privatlivspolitik for websteder</a> og <a>betingelser for brug af websteder</a>.
deletePopupText = Slet denne fil?
deletePopupYes = Ja
deletePopupCancel = Annuller
deleteButtonHover = Slet
copyUrlHover = Kopier URL
footerLinkLegal = Juridisk
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Om Testpilot
footerLinkPrivacy = Privatliv
footerLinkTerms = Betingelser
footerLinkCookies = Cookies
requirePasswordCheckbox = Kræv an adgangskode for at hente denne fil
addPasswordButton = Tilføj adgangskode
changePasswordButton = Skift
passwordTryAgain = Forkert adgangskode. Prøv igen.
reportIPInfringement = Rapporter krænkelse af intellektuel ejendomsret
javascriptRequired = Firefox Send kræver JavaScript
whyJavascript = Hvorfor kræver Firefox Send JavaScript?
enableJavascript = Aktiver JavaScript og prøv igen.
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours } t { $minutes } m
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes } m
# A short status message shown when a password is successfully set
passwordIsSet = Adgangskode sat
# A short status message shown when the user enters a long password
maxPasswordLength = Maksimum længde af adgangskode: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = Adgangskoden kunne ikke sættes

View File

@@ -20,17 +20,19 @@ notifyUploadDone = Ihr Upload ist abgeschlossen.
uploadingPageMessage = Sobald Ihre Datei hochgeladen wird, können Sie die Optionen zum Ablaufdatum auswählen.
uploadingPageCancel = Hochladen abbrechen
uploadCancelNotification = Ihr Upload wurde abgebrochen.
uploadingPageLargeFileMessage = Diese Datei ist groß, sodass das hochladen einige Zeit dauern könnte. Haben Sie Geduld!
uploadingPageLargeFileMessage = Diese Datei ist groß, sodass das Hochladen einige Zeit dauern könnte. Haben Sie Geduld!
uploadingFileNotification = Mich benachrichtigen, wenn der Upload abgeschlossen ist.
uploadSuccessConfirmHeader = Bereit zum Senden
uploadSvgAlt = Hochladen
uploadSuccessTimingHeader = Der Link zu Ihrer Datei läuft nach einem Download oder in 24 Stunden ab.
expireInfo = Der Link zu Ihrer Datei läuft nach { $downloadCount } oder { $timespan } ab.
downloadCount = { $num ->
downloadCount =
{ $num ->
[one] einem Download
*[other] { $num } Downloads
}
timespanHours = { $num ->
timespanHours =
{ $num ->
[one] einer Stunde
*[other] { $num } Stunden
}
@@ -86,7 +88,7 @@ expiryFileList = Läuft ab in
deleteFileList = Löschen
nevermindButton = Egal
legalHeader = Nutzungsbedingungen und Datenschutz
legalNoticeTestPilot = Firefox Send ist aktuell ein Test-Pilot-Experiment und unterliegt den <a>Nutzungsbedingungen</a> und dem <a>Datenschutzhinweis</a> von Test Pilot. Mehr über diese Experiment und die Daten, die es sammelt, erfahren Sie <a>hier</a>.
legalNoticeTestPilot = Firefox Send ist aktuell ein Test-Pilot-Experiment und unterliegt den <a>Nutzungsbedingungen</a> und dem <a>Datenschutzhinweis</a> von Test Pilot. Mehr über dieses Experiment und die Daten, die es sammelt, erfahren Sie <a>hier</a>.
legalNoticeMozilla = Die Nutzung der Website von Firefox Send unterliegt außerdem Mozillas <a>Datenschutzhinweis für Websites</a> und <a>Nutzungsbedingungen für Websites</a>.
deletePopupText = Diese Datei löschen?
deletePopupYes = Ja
@@ -106,7 +108,7 @@ passwordTryAgain = Falsches Passwort. Versuchen Sie es erneut.
reportIPInfringement = IP-Verletzung melden
javascriptRequired = Firefox Send benötigt JavaScript
whyJavascript = Warum benötigt Firefox Send JavaScript?
enableJavascript = Bitte akivieren Sie JavaScript und versuchen Sie es erneut.
enableJavascript = Bitte aktivieren Sie JavaScript und versuchen Sie es erneut.
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours }h { $minutes }m
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = πείραμα διαδικτύου
siteFeedback = Σχόλια
@@ -39,29 +39,29 @@ copyUrlFormButton = Αντιγραφή στο πρόχειρο
copiedUrl = Αντιγράφτηκε!
deleteFileButton = Διαγραφή αρχείου
sendAnotherFileLink = Αποστολή άλλου αρχείου
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = Λήψη
downloadsFileList = Λήψεις
// Used as header in a column indicating the amount of time left before a
// download link expires (e.g. "10h 5m")
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = Ώρα
// Used as header in a column indicating the number of times a file has been
// downloaded
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = Λήψη του { $filename }
downloadFileSize = ({ $size })
unlockInputLabel = Εισαγωγή κωδικού πρόσβασης
unlockInputPlaceholder = Κωδικός πρόσβασης
unlockButtonLabel = Ξεκλείδωμα
downloadFileTitle = Λήψη κρυπτογραφημένου αρχείου
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
downloadMessage = Ο/Η φίλος/-η σας, σάς στέλνει ένα αρχείο με τη βοήθεια του Firefox Send, μιας υπηρεσίας που επιτρέπει τον διαμοιρασμό αρχείων μέσω ενός ασφαλούς, ιδιωτικού και κρυπτογραφημένου συνδέσμου που λήγει αυτόματα, ώστε να είστε σίγουροι ότι τα αρχεία σας δεν θα παραμείνουν στο διαδίκτυο για πάντα.
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Λήψη
downloadNotification = Η λήψη σας ολοκληρώθηκε.
downloadFinish = Η λήψη ολοκληρώθηκε
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } από { $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Δοκιμάστε το Firefox Send
downloadingPageProgress = Γίνεται λήψη του { $filename } ({ $size })
downloadingPageMessage = Παρακαλώ αφήστε ανοικτή αυτή την καρτέλα όσο λαμβάνουμε και αποκρυπτογραφούμε το αρχείο σας.
@@ -73,7 +73,7 @@ fileTooBig = Αυτό το αρχείο είναι πολύ μεγάλο για
linkExpiredAlt = Ο σύνδεσμος έληξε
expiredPageHeader = Αυτός ο σύνδεσμος έχει λήξει ή δεν υπήρξε ποτέ!
notSupportedHeader = Το πρόγραμμα περιήγησής σας δεν υποστηρίζεται.
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = Δυστυχώς, αυτό το πρόγραμμα περιήγησης δεν υποστηρίζει την τεχνολογία ιστού στην οποία βασίζεται το Firefox Send. Θα πρέπει να δοκιμάσετε ένα άλλο πρόγραμμα περιήγησης. Προτείνουμε το Firefox!
notSupportedLink = Γιατί δεν υποστηρίζεται το πρόγραμμα περιήγησής μου;
notSupportedOutdatedDetail = Δυστυχώς, αυτή η έκδοση του Firefox δεν υποστηρίζει την τεχνολογία ιστού στην οποία βασίζεται το Firefox Send. Πρέπει να ενημερώσετε το πρόγραμμα περιήγησής σας.
@@ -81,7 +81,7 @@ updateFirefox = Ενημέρωση Firefox
downloadFirefoxButtonSub = Δωρεάν λήψη
uploadedFile = Αρχείο
copyFileList = Αντιγραφή URL
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = Λήγει σε
deleteFileList = Διαγραφή
nevermindButton = Μην ανησυχείτε
@@ -94,7 +94,7 @@ deletePopupCancel = Ακύρωση
deleteButtonHover = Διαγραφή
copyUrlHover = Αντιγραφή URL
footerLinkLegal = Νομικά
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Σχετικά με το Test Pilot
footerLinkPrivacy = Απόρρητο
footerLinkTerms = Όροι
@@ -103,13 +103,17 @@ requirePasswordCheckbox = Απαίτηση κωδικού πρόσβασης γ
addPasswordButton = Προσθήκη κωδικού πρόσβασης
changePasswordButton = Αλλαγή
passwordTryAgain = Λάθος κωδικός πρόσβασης. Δοκιμάστε ξανά.
// This label is followed by the password needed to download a file
passwordResult = Κωδικός πρόσβασης: { $password }
reportIPInfringement = Αναφορά παραβίασης IP
javascriptRequired = Το Firefox Send απαιτεί JavaScript
whyJavascript = Γιατί το Firefox Send απαιτεί JavaScript;
enableJavascript = Παρακαλώ ενεργοποιήστε το JavaScript και δοκιμάστε ξανά.
// A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours }ώ { $minutes }λ
// A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes }λ
# A short status message shown when a password is successfully set
passwordIsSet = Επιτυχής ορισμός κωδικού
# A short status message shown when the user enters a long password
maxPasswordLength = Μέγιστο μήκος κωδικού: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = Δεν ήταν δυνατός ο ορισμός αυτού του κωδικού

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = experimento web
siteFeedback = Opinión
@@ -39,29 +39,29 @@ copyUrlFormButton = Copiar al portapapeles
copiedUrl = ¡Copiado!
deleteFileButton = Borrar archivo
sendAnotherFileLink = Enviar otro archivo
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = Descargar
downloadsFileList = Descargas
// Used as header in a column indicating the amount of time left before a
// download link expires (e.g. "10h 5m")
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = Tiempo
// Used as header in a column indicating the number of times a file has been
// downloaded
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = Descargar { $filename }
downloadFileSize = ({ $size })
unlockInputLabel = Ingresar contraseña
unlockInputPlaceholder = Contraseña
unlockButtonLabel = Desbloquear
downloadFileTitle = Descargar archivo cifrado
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
downloadMessage = Tu amigo te está enviando un archivo con Firefox Send, un servicio que permite compartir archivos con un enlace cifrado, seguro y privado que expira automáticamente para asegurar que tus datos no quedan en línea para siempre.
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Descargar
downloadNotification = La descarga se completó.
downloadFinish = Descarga completa
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } de { $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Probá Firefox Send
downloadingPageProgress = Descargando { $filename } ({ $size })
downloadingPageMessage = Dejá esta pestaña abierta mientras descargamos el archivo y lo desciframos.
@@ -73,7 +73,7 @@ fileTooBig = El archivo es demasiado grande para subir. Debería tener menos de
linkExpiredAlt = Enlace explirado
expiredPageHeader = ¡Este enlace ha expirado o nunca existió en primer lugar!
notSupportedHeader = El navegador no está soportado.
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = Desafortunadamente este navegador no soporta la tecnología web que necesita Firefox Send. Deberías probar otro navegador. ¡Te recomendamos Firefox!
notSupportedLink = ¿Por qué mi navegador no está soportado?
notSupportedOutdatedDetail = Desafortunadamente esta versión de Firefox no soporta la tecnología web que necesita Firefox Send. Necesitás actualizar el navegador.
@@ -81,7 +81,7 @@ updateFirefox = Actualizar Firefox
downloadFirefoxButtonSub = Descarga gratuita
uploadedFile = Archivo
copyFileList = Copiar URL
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = Expira en
deleteFileList = Borrar
nevermindButton = No importa
@@ -94,7 +94,7 @@ deletePopupCancel = Cancelar
deleteButtonHover = Borrar
copyUrlHover = Copiar URL
footerLinkLegal = Legales
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Acerca de Test Pilot
footerLinkPrivacy = Privacidad
footerLinkTerms = Términos
@@ -103,13 +103,17 @@ requirePasswordCheckbox = Requerir contraseña para descargar este archivo
addPasswordButton = Agregar contraseña
changePasswordButton = Cambiar
passwordTryAgain = Contraseña incorrecta. Intentá nuevamente.
// This label is followed by the password needed to download a file
passwordResult = Contraseña: { $password }
reportIPInfringement = Informar violación de propiedad intelectual
javascriptRequired = Firefox Send requiere JavaScript
whyJavascript = ¿Por qué Firefox Send requiere Java Script?
enableJavascript = Por favor habilite JavaScript y pruebe de nuevo.
// A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = h { $hours } m { $minutes }
// A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = m { $minutes }
# A short status message shown when a password is successfully set
passwordIsSet = Contraseña establecida
# A short status message shown when the user enters a long password
maxPasswordLength = Longitud máxima de la contraseña: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = No se pudo establecer la contraseña

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = experimento web
siteFeedback = Comentarios
@@ -39,29 +39,29 @@ copyUrlFormButton = Copiar al portapapeles
copiedUrl = ¡Copiado!
deleteFileButton = Eliminar archivo
sendAnotherFileLink = Enviar otro archivo
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = Descargar
downloadsFileList = Descargas
// Used as header in a column indicating the amount of time left before a
// download link expires (e.g. "10h 5m")
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = Tiempo
// Used as header in a column indicating the number of times a file has been
// downloaded
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = Descargar { $filename }
downloadFileSize = ({ $size })
unlockInputLabel = Ingresar contraseña
unlockInputPlaceholder = Contraseña
unlockButtonLabel = Desbloquear
downloadFileTitle = Bajar archivo cifrado
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
downloadMessage = Tu amigo te está enviando un archivo con Firefox Send, un servicio que te permite compartir archivos con un enlace seguro, privado y cifrado que expira automáticamente para asegurar que tus cosas no queden en línea de por vida.
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Descargar
downloadNotification = Tu descarga se completó.
downloadFinish = Descarga completa
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } de { $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Probar Firefox Send
downloadingPageProgress = Descargando { $filename } ({ $size })
downloadingPageMessage = Por favor, deja esta pestaña abierta mientras recibimos tu archivo y lo desciframos.
@@ -73,7 +73,7 @@ fileTooBig = Ese archivo es muy grande para ser subido. Debiera tener un tamaño
linkExpiredAlt = Enlace expirado
expiredPageHeader = ¡Este enlace ha expirado o quizá jamás existió!
notSupportedHeader = Tu navegador no está soportado.
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = Lamentablemente este navegador no soporta la tecnología web que potencia a Firefox Send. Deberás probar en otro navegador. ¡Recomendamos Firefox!
notSupportedLink = ¿Por qué mi navegador no es soportado?
notSupportedOutdatedDetail = Lamentablemente esta versión de Firefox no soporta la tecnología web que potencia a Firefox Send. Deberás actualizar tu navegador.
@@ -81,7 +81,7 @@ updateFirefox = Actualizar Firefox
downloadFirefoxButtonSub = Descarga gratuita
uploadedFile = Archivo
copyFileList = Copiar URL
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = Expira en
deleteFileList = Eliminar
nevermindButton = Da lo mismo
@@ -94,7 +94,7 @@ deletePopupCancel = Cancelar
deleteButtonHover = Eliminar
copyUrlHover = Copiar URL
footerLinkLegal = Legal
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Acerca de Test Pilot
footerLinkPrivacy = Privacidad
footerLinkTerms = Términos
@@ -103,13 +103,17 @@ requirePasswordCheckbox = Requerir una contraseña para descargar este archivo
addPasswordButton = Añadir contraseña
changePasswordButton = Cambiar
passwordTryAgain = Contraseña incorrecta. Vuelve a intentarlo.
// This label is followed by the password needed to download a file
passwordResult = Contraseña: { $password }
reportIPInfringement = Reportar infracción de PI
javascriptRequired = Firefox Send requiere JavaScript.
whyJavascript = ¿Por qué Firefox Send requiere JavaScript?
enableJavascript = Por favor, activa JavaScript y vuelve a intentarlo.
// A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours }h { $minutes }m
// A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes }m
# A short status message shown when a password is successfully set
passwordIsSet = Contraseña establecida
# A short status message shown when the user enters a long password
maxPasswordLength = Longitud máxima de la contraseña: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = Esta contraseña no pudo ser establecida

View File

@@ -26,10 +26,12 @@ uploadSuccessConfirmHeader = Listo para enviar
uploadSvgAlt = Subir
uploadSuccessTimingHeader = El enlace a tu archivo expirará después de una descarga o en 24 horas.
expireInfo = El enlace a tu archivo expirará después de { $downloadCount } o { $timespan }.
downloadCount = { $num ->
downloadCount =
{ $num ->
*[one] 1 descarga
}
timespanHours = { $num ->
timespanHours =
{ $num ->
[one] 1 hora
*[other] { $num } horas
}
@@ -102,8 +104,6 @@ requirePasswordCheckbox = Se necesita una contraseña para descargar este archiv
addPasswordButton = Agregar contraseña
changePasswordButton = Cambiar
passwordTryAgain = Contraseña incorrecta. Intenta de nuevo.
# This label is followed by the password needed to download a file
passwordResult = Contraseña: { $password }
reportIPInfringement = Denunciar una infracción de PI
javascriptRequired = Firefox Send requiere JavaScript
whyJavascript = ¿Por qué Firefox Send requiere JavaScript?
@@ -114,3 +114,7 @@ expiresHoursMinutes = { $hours }h { $minutes }m
expiresMinutes = { $minutes }m
# A short status message shown when a password is successfully set
passwordIsSet = Contraseña establecida
# A short status message shown when the user enters a long password
maxPasswordLength = Longitud máxima de la contraseña: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = No se ha podido establecer la contraseña

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = veebieksperiment
siteFeedback = Tagasiside
@@ -39,29 +39,29 @@ copyUrlFormButton = Kopeeri vahemällu
copiedUrl = Kopeeritud!
deleteFileButton = Kustuta fail
sendAnotherFileLink = Saada järgmine fail
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = Laadi alla
downloadsFileList = Allalaadimised
// Used as header in a column indicating the amount of time left before a
// download link expires (e.g. "10h 5m")
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = Aega jäänud
// Used as header in a column indicating the number of times a file has been
// downloaded
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = Laadi fail { $filename } alla
downloadFileSize = ({ $size })
unlockInputLabel = Sisesta parool
unlockInputPlaceholder = Parool
unlockButtonLabel = Ava
downloadFileTitle = Krüptitud faili allalaadimine
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
downloadMessage = Sulle on saadetud fail Firefox Sendiga - teenusega, mis lubab faile ohutult, privaatselt ja krüpteeritult jagada. Failid kustutatakse automaatselt, et need ei jääks internetti igaveseks.
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Laadi alla
downloadNotification = Allalaadimine on lõpetatud.
downloadFinish = Allalaadimine lõpetati
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize }/{ $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Proovi Firefox Sendi
downloadingPageProgress = Faili { $filename } ({ $size }) allalaadimine
downloadingPageMessage = Palun jäta see kaart lahti, kuni fail on alla laaditud ja dekrüptitud.
@@ -73,7 +73,7 @@ fileTooBig = Fail on üleslaadimiseks liiga suur. See peaks olema väiksem kui {
linkExpiredAlt = Link on aegunud
expiredPageHeader = See link on aegunud või seda pole kunagi olnudki!
notSupportedHeader = Sinu brauser pole toetatud.
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = Kahjuks ei toeta see brauser veebitehnoloogiaid, mis teevad Firefox Sendi toimimise võimalikuks. Sa pead proovima teise brauseriga. Me soovitame Firefoxi!
notSupportedLink = Miks mu brauser toetatud pole?
notSupportedOutdatedDetail = Kahjuks ei toeta see Firefoxi versioon veebitehnoloogiaid, mis teevad Firefox Sendi toimimise võimalikuks. Sa pead oma brauserit uuendama.
@@ -81,7 +81,7 @@ updateFirefox = Uuenda Firefox
downloadFirefoxButtonSub = Laadi alla tasuta
uploadedFile = Fail
copyFileList = Kopeeri URL
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = Aegub
deleteFileList = Kustuta
nevermindButton = Ära pane tähele
@@ -94,7 +94,7 @@ deletePopupCancel = Loobu
deleteButtonHover = Kustuta
copyUrlHover = Kopeeri URL
footerLinkLegal = Õiguslik teave
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Test Pilotist
footerLinkPrivacy = Privaatsusest
footerLinkTerms = Teenusetingimused
@@ -103,13 +103,17 @@ requirePasswordCheckbox = Selle faili allalaadimiseks nõutakse parooli
addPasswordButton = Lisa parool
changePasswordButton = Muuda
passwordTryAgain = Vale parool. Palun proovi uuesti.
// This label is followed by the password needed to download a file
passwordResult = Parool: { $password }
reportIPInfringement = Intellektuaalomandi keelatud kasutamise raporteerimine
javascriptRequired = Firefox Send'i kasutamiseks tuleb JavaScript lubada
whyJavascript = Miks Firefox Send JavaScripti vajab?
enableJavascript = Palun luba JavaScript ja proovi uuesti.
// A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours }t { $minutes }m
// A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes }m
# A short status message shown when a password is successfully set
passwordIsSet = Parool on muudetud
# A short status message shown when the user enters a long password
maxPasswordLength = Maksimaalne parooli pikkus: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = Parooli muutmine ebaõnnestus

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = آزمایش وب
siteFeedback = بازخورد
@@ -26,40 +26,34 @@ uploadSuccessConfirmHeader = آماده برای ارسال
uploadSvgAlt = بارگذاری
uploadSuccessTimingHeader = پیوند به پرونده شما بعد از ۱ بار دانلود یا ۲۴ ساعت حذف خواهد شد.
expireInfo = این پیوند به فایل شما پس از { $downloadCount } یا { $timespan } منقضی خواهد شد.
downloadCount = { $num ->
*[other] ۱ بارگذاری
}
timespanHours = { $num ->
*[other] ۱ ساعت
}
copyUrlFormLabelWithName = برای ارسال پرونده پیوند آن را رونوشت و به اشتراک بگذارید: { $filename }
copyUrlFormButton = رونوشت به کلیپ‌بورد
copiedUrl = رونوشت شد!
deleteFileButton = حذف پرونده
sendAnotherFileLink = ارسال پرونده دیگر
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = دریافت
downloadsFileList = دریافت‌ها
// Used as header in a column indicating the amount of time left before a
// download link expires (e.g. "10h 5m")
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = زمان
// Used as header in a column indicating the number of times a file has been
// downloaded
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = بارگیری { $filename }
downloadFileSize = ({ $size })
unlockInputLabel = گذرواژه را وارد کنید
unlockInputPlaceholder = گذرواژه
unlockButtonLabel = باز کردن
downloadFileTitle = دریافت پروندهٔ رمزنگاری شده
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
downloadMessage = دوست شما درحال ارسال پرونده ای به وسیله Firefox Send است،‌ این سرویس این امکان را به شما می‌دهد تا پرونده‌های خود را به صورت ایمن،‌خصوصی و رمزنگاری شده به همراه پیوند انقضا خودکار همرسانی کنید تا اطمینان حاصل کنید چیزهای شما برای همیشه آنلاین باقی نخواهد ماند.
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = بارگیری
downloadNotification = بارگیری شما کامل شد.
downloadFinish = بارگیری کامل شد
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } از { $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Firefox Send را امتحان کنید
downloadingPageProgress = دریافت { $filename } ({ $size })
downloadingPageMessage = لطفا این زبانه را باز بگذارید در حالی که ما فایل شما را دریافت می‌کنیم و کدگذاری می‌کنیم.
@@ -71,7 +65,7 @@ fileTooBig = این پرونده بسیار حجیم است. حجم آن می‌
linkExpiredAlt = پیوند منقضی شده است
expiredPageHeader = پیوند منقضی شده است یا در از همان ابتدا وجود نداشته است!
notSupportedHeader = مرورگر شما پشتیبانی نمی‌کند.
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = متاسفانه این مرورگر این تکنولوژی وب را که به Firefox Send قدرت می‌بخشد را پشتیبانی نمی‌کند. شما بایستی مرورگری دیگری را امتحان کنید. پیشنهاد ما به شما فایرفاکس است !
notSupportedLink = چرا مرورگر من پشتیبانی نمی‌کند؟
notSupportedOutdatedDetail = متاسفانه این نسخه از فایرفاکس این تکنولوژی وب که به Firefox Send قدرت می‌بخشد را پشتیبانی نمی‌کند. شما نیاز دارید تا مرورگر خود را بروز کنید.
@@ -79,7 +73,7 @@ updateFirefox = بروزرسانی فایرفاکس
downloadFirefoxButtonSub = دریافت رایگان
uploadedFile = پرونده‌
copyFileList = رونوشت از نشانی
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = زمان انقضا
deleteFileList = حذف
nevermindButton = بیخیال
@@ -92,7 +86,7 @@ deletePopupCancel = انصراف
deleteButtonHover = حذف
copyUrlHover = رونوشت از نشانی
footerLinkLegal = ملاحظات حقوقی
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = درباره Test Pilot
footerLinkPrivacy = حریم‌خصوصی
footerLinkTerms = شرایط
@@ -101,13 +95,17 @@ requirePasswordCheckbox = دریافت این پرونده نیاز به گذر
addPasswordButton = افزودن گذرواژه
changePasswordButton = تغییر
passwordTryAgain = کلمه عبور اشتباه است. مجدد تلاش کنید.
// This label is followed by the password needed to download a file
passwordResult = گذرواژه: { $password }
reportIPInfringement = گزارش تخلف IP
javascriptRequired = Firefox Send نیازمند جاوااسکریپت است
whyJavascript = چراFirefox Send جاوااسکریپت لازم دارد؟
enableJavascript = لطفا جاوااسکریپت را فعال کنید و مجددا تلاش کنید.
// A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours }ساعت { $minutes }دقیقه
// A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes } دقیقه
# A short status message shown when a password is successfully set
passwordIsSet = گذرواژه تنظیم شد
# A short status message shown when the user enters a long password
maxPasswordLength = حداکثر اندازهٔ گذرواژه: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = امکان ثبت این گذواژه نیست

View File

@@ -103,8 +103,6 @@ requirePasswordCheckbox = Om dit bestân te downloaden is in wachtwurd fereaske
addPasswordButton = Wachtwurd tafoegje
changePasswordButton = Wizigje
passwordTryAgain = Net krekt wachtwurd. Probearje it opnij.
# This label is followed by the password needed to download a file
passwordResult = Wachtwurd: { $password }
reportIPInfringement = IP-ynbrek melde
javascriptRequired = Firefox Send fereasket JavaScript.
whyJavascript = Werom hat Firefox Send JavaScript nedich?
@@ -115,3 +113,7 @@ expiresHoursMinutes = { $hours }o { $minutes }m
expiresMinutes = { $minutes }m
# A short status message shown when a password is successfully set
passwordIsSet = Wachtwurd ynsteld
# A short status message shown when the user enters a long password
maxPasswordLength = Maksimale wachtwurdlingte: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = Dit wachtwurd koe net ynsteld wurde

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = un experimento web
siteFeedback = Reaction
@@ -39,29 +39,29 @@ copyUrlFormButton = Copiar al area de transferentia
copiedUrl = Copiate!
deleteFileButton = Deler le file
sendAnotherFileLink = Inviar un altere file
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = Discargar
downloadsFileList = Discargamentos
// Used as header in a column indicating the amount of time left before a
// download link expires (e.g. "10h 5m")
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = Tempore
// Used as header in a column indicating the number of times a file has been
// downloaded
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = Discargar { $filename }
downloadFileSize = ({ $size })
unlockInputLabel = Insere le contrasigno
unlockInputPlaceholder = Contrasigno
unlockButtonLabel = Disblocar
downloadFileTitle = Discargar le file cryptate
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
downloadMessage = Tu amico te invia un file per Firefox Send, un servicio que te permitte de compartir files per un ligamine secur, private e cryptate, que expira automaticamente pro te assecurar que tu datos non resta online per sempre.
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Discargar
downloadNotification = Tu discargamento es completate.
downloadFinish = Discargamento completate
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } de { $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Proba Firefox Send
downloadingPageProgress = Discargamento de { $filename } ({ $size })
downloadingPageMessage = Per favor lassa iste scheda aperte durante que nos prende tu file e lo decifra.
@@ -73,7 +73,7 @@ fileTooBig = Iste file es troppo grande pro lo cargar. Illo debe ser inferior a
linkExpiredAlt = Ligamine expirate
expiredPageHeader = Iste ligamine expirava o illo non existeva jammais!
notSupportedHeader = Tu navigator non es supportate
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = Infelicemente iste navigator non supporta le nove technologias web que move Firefox Send. Tu besonia de probar un altere navigator. Nos recommenda Firefox!
notSupportedLink = Perque iste navigator non es supportate?
notSupportedOutdatedDetail = Infelicemente iste version de Firefox non supporta le nove technologias web que move Firefox Send. Tu besonia de actualisar tu navigator.
@@ -81,7 +81,7 @@ updateFirefox = Actualisar Firefox
downloadFirefoxButtonSub = Discargamento gratuite
uploadedFile = File
copyFileList = Copiar le URL
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = Expira in
deleteFileList = Deler
nevermindButton = No, gratias
@@ -94,7 +94,7 @@ deletePopupCancel = Cancellar
deleteButtonHover = Deler
copyUrlHover = Copiar le URL
footerLinkLegal = Legal
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Re Test Pilot
footerLinkPrivacy = Confidentialitate
footerLinkTerms = Terminos
@@ -103,13 +103,17 @@ requirePasswordCheckbox = Requirer un contrasigno pro discargar iste file
addPasswordButton = Adder contrasigno
changePasswordButton = Cambiar
passwordTryAgain = Contrasigno incorrecte. Retenta.
// This label is followed by the password needed to download a file
passwordResult = Contrasigno: { $password }
reportIPInfringement = Reportar un violation de proprietate intellectual
javascriptRequired = Firefox Send require JavaScript
whyJavascript = Proque Firefox Send require JavaScript?
enableJavascript = Por favor activa JavaScript e tenta novemente.
// A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours }h { $minutes }m
// A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes }m
# A short status message shown when a password is successfully set
passwordIsSet = Configuration del contrasigno
# A short status message shown when the user enters a long password
maxPasswordLength = Maxime longor del contrasigno: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = Iste contrasigno non pote ser definite

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = eksperimen web
siteFeedback = Saran
@@ -27,10 +27,12 @@ uploadSuccessConfirmHeader = Siap untuk Dikirim
uploadSvgAlt = Unggah
uploadSuccessTimingHeader = Tautan ke berkas Anda akan berakhir setelah 1 unduhan atau dalam 24 jam.
expireInfo = Tautan ke berkas Anda akan kedaluwarsa setelah { $downloadCount } atau { $timespan }.
downloadCount = { $num ->
downloadCount =
{ $num ->
*[other] { $number } unduhan
}
timespanHours = { $num ->
timespanHours =
{ $num ->
*[other] { $number } jam
}
copyUrlFormLabelWithName = Salin dan bagikan tautan untuk mengirim berkas Anda: { $filename }
@@ -38,23 +40,29 @@ copyUrlFormButton = Salin ke papan klip
copiedUrl = Tersalin!
deleteFileButton = Hapus berkas
sendAnotherFileLink = Kirim berkas lain
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = Unduh
downloadsFileList = Unduhan
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = Waktu
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = Unduh { $filename }
downloadFileSize = ({ $size })
unlockInputLabel = Masukkan Sandi
unlockInputPlaceholder = Sandi
unlockButtonLabel = Buka
downloadFileTitle = Unduh Berkas Terenkripsi
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
downloadMessage = Teman Anda mengirimkan berkas dengan Firefox Send, layanan yang memungkinkan Anda berbagi berkas dengan tautan yang aman, pribadi, dan terenkripsi yang secara otomatis berakhir untuk memastikan berkas Anda tidak daring selamanya.
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Unduh
downloadNotification = Unduhan Anda telah selesai.
downloadFinish = Unduhan Selesai
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } dari { $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Coba Firefox Send
downloadingPageProgress = Mengunduh { $filename } ({ $size })
downloadingPageMessage = Sila biarkan tab ini terbuka sementara kami memproses berkas Anda dan mendekripsinya.
@@ -66,7 +74,7 @@ fileTooBig = Berkas terlalu besar untuk diunggah. Harus kurang dari { $size }.
linkExpiredAlt = Tautan kedaluwarsa
expiredPageHeader = Tautan ini telah kedaluwarsa atau tidak pernah ada!
notSupportedHeader = Peramban Anda tidak mendukung.
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = Sayangnya peramban ini tidak mendukung teknologi web yang menggerakkan Firefox Send. Anda perlu mencoba peramban lain. Kami merekomendasikan Firefox!
notSupportedLink = Mengapa peramban saya tidak didukung?
notSupportedOutdatedDetail = Sayangnya Firefox versi ini tidak mendukung teknologi web yang menggerakkan Firefox Send. Anda perlu memperbarui peramban Anda.
@@ -74,7 +82,7 @@ updateFirefox = Perbarui Firefox
downloadFirefoxButtonSub = Unduh Gratis
uploadedFile = Berkas
copyFileList = Salin URL
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = Kedaluwarsa Pada
deleteFileList = Hapus
nevermindButton = Abaikan
@@ -87,14 +95,22 @@ deletePopupCancel = Batal
deleteButtonHover = Hapus
copyUrlHover = Salin URL
footerLinkLegal = Legal
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Tentang Test Pilot
footerLinkPrivacy = Privasi
footerLinkTerms = Ketentuan
footerLinkCookies = Kuki
requirePasswordCheckbox = Membutuhkan sandi untuk mengunduh berkas ini
addPasswordButton = Tambahkan Sandi
changePasswordButton = Ubah
passwordTryAgain = Sandi salah. Silakan coba lagi.
// This label is followed by the password needed to download a file
passwordResult = Sandi: { $password }
reportIPInfringement = Laporkan Pelanggaran IP
javascriptRequired = Firefox Send membutuhkan JavaScript.
whyJavascript = Mengapa Firefox Send membutuhkan JavaScript?
enableJavascript = Silakan aktifkan JavaScript dan coba lagi.
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours }j { $minutes }m
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes }m
# A short status message shown when the user enters a long password
maxPasswordLength = Panjang sandi maksimal: { $length }

View File

@@ -26,10 +26,14 @@ uploadSuccessConfirmHeader = მზადაა გასაგზავნა
uploadSvgAlt = ატვირთვა
uploadSuccessTimingHeader = ფაილს ვადა გაუვა 1 ჩამოტვირთვის, ან 24 საათის მერე.
expireInfo = ფაილის ბმულს, ვადა გაუვა { $downloadCount }, ან { $timespan } მერე.
downloadCount = { $num ->
downloadCount =
{ $num ->
[one] 1 ჩამოტვირთვა
*[other] { $num } ჩამოტვირთვა
}
timespanHours = { $num ->
timespanHours =
{ $num ->
[one] 1 საათი
*[other] { $num } საათი
}
copyUrlFormLabelWithName = დააკოპირეთ და გააზიარეთ ბმული, ფაილის გასაგზავნად: { $filename }

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = 웹 실험
siteFeedback = 사용자 의견
@@ -34,23 +34,29 @@ copyUrlFormButton = 클립보드에 복사
copiedUrl = 복사 완료!
deleteFileButton = 파일 삭제
sendAnotherFileLink = 다른 파일 보내기
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = 다운로드
downloadsFileList = 다운로드
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = 남은 시간
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = { $filename } 다운로드
downloadFileSize = ({ $size })
unlockInputLabel = 비밀번호 입력
unlockInputPlaceholder = 비밀번호
unlockButtonLabel = 잠금 해제
downloadFileTitle = 암호화된 파일 다운로드
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
downloadMessage = 당신의 친구가 Firefox Send를 통해 파일을 보내고 있습니다. 이 서비스는 안전하고, 개인적이며, 암호화된 링크를 통해 파일을 공유하는 서비스입니다. 사용자의 파일이 더 이상 온라인 상에 남지 않도록 링크는 자동적으로 만료됩니다.
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = 다운로드
downloadNotification = 다운로드가 완료되었습니다.
downloadFinish = 다운로드 완료
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } / { $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Firefox Send 써보기
downloadingPageProgress = { $filename } ({ $size }) 다운로드 중
downloadingPageMessage = 파일을 가져오고 복호화하는 동안 탭을 닫지 말아주세요.
@@ -62,7 +68,7 @@ fileTooBig = 파일의 크기가 너무 큽니다. { $size } 보다 작아야
linkExpiredAlt = 링크가 만료됨
expiredPageHeader = 이 링크는 만료되었거나 애초부터 존재하지 않았습니다!
notSupportedHeader = 이 브라우저는 지원되지 않습니다.
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = 안타깝게도 이 브라우저는 Firefox Send에 사용되는 웹 기술을 지원하지 않습니다. 다른 브라우저로 다시 시도해주세요. Firefox를 추천합니다!
notSupportedLink = 왜 이 브라우저는 지원이 되지 않나요?
notSupportedOutdatedDetail = 안타깝게도 현재 브라우저 버전에서는 Firefox Send에 사용되는 웹 기술을 지원하지 않습니다. 브라우저 업데이트가 필요합니다.
@@ -70,7 +76,7 @@ updateFirefox = Firefox 업데이트
downloadFirefoxButtonSub = 무료 다운로드
uploadedFile = 파일
copyFileList = URL 복사
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = 만료기한
deleteFileList = 삭제
nevermindButton = 괜찮습니다
@@ -83,14 +89,26 @@ deletePopupCancel = 아니오
deleteButtonHover = 삭제
copyUrlHover = URL 복사
footerLinkLegal = 법적 정보
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Test Pilot 정보
footerLinkPrivacy = 개인정보 보호
footerLinkTerms = 이용 약관
footerLinkCookies = 쿠키
requirePasswordCheckbox = 이 파일을 다운로드하려면 비밀번호가 필요함
addPasswordButton = 비밀번호 추가
changePasswordButton = 바꾸기
passwordTryAgain = 비밀번호가 맞지 않습니다. 다시 시도해 주세요.
// This label is followed by the password needed to download a file
passwordResult = 비밀번호: { $password }
reportIPInfringement = 지적 재산권 침해 신고
javascriptRequired = Firefox Send는 자바스크립트를 필요로 합니다
whyJavascript = 왜 Firefox Send에 자바스크립트가 필요하죠?
enableJavascript = 자바스크립트를 활성화하고 다시 시도해 주세요.
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours }시간 { $minutes }분
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes }분
# A short status message shown when a password is successfully set
passwordIsSet = 비밀번호를 설정했습니다
# A short status message shown when the user enters a long password
maxPasswordLength = 최대 비밀번호 길이: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = 이 비밀번호를 설정할 수 없었습니다

View File

@@ -103,8 +103,6 @@ requirePasswordCheckbox = Krever et passord for å laste ned denne filen
addPasswordButton = Legg til passord
changePasswordButton = Endre
passwordTryAgain = Feil passord. Prøv igjen.
# This label is followed by the password needed to download a file
passwordResult = Passord: { $password }
reportIPInfringement = Rapporter brudd på åndsverk
javascriptRequired = Firefox Send krever JavaScript.
whyJavascript = Hvorfor krever Firefox Send JavaScript?
@@ -115,3 +113,7 @@ expiresHoursMinutes = { $hours }t { $minutes }m
expiresMinutes = { $minutes }m
# A short status message shown when a password is successfully set
passwordIsSet = Passord satt
# A short status message shown when the user enters a long password
maxPasswordLength = Maksimum passordlengde: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = Dette passordet kunne ikke settes

View File

@@ -8,7 +8,7 @@ uploadPageLearnMore = Saber mais
uploadPageDropMessage = Largue o seu ficheiro aqui para começar a carregar
uploadPageSizeMessage = Para uma operação mais confiável, é melhor manter o seu ficheiro abaixo de 1GB
uploadPageBrowseButton = Selecionar um ficheiro no seu computador
uploadPageBrowseButton1 = Selecione um ficheiro a enviar
uploadPageBrowseButton1 = Selecionar um ficheiro a carregar
uploadPageMultipleFilesAlert = Carregar múltiplos ficheiros ou uma pasta não é atualmente suportado.
uploadPageBrowseButtonTitle = Carregar ficheiro
uploadingPageProgress = A carregar { $filename } ({ $size })
@@ -26,7 +26,8 @@ uploadSuccessConfirmHeader = Pronto para enviar
uploadSvgAlt = Carregar
uploadSuccessTimingHeader = A ligação para o seu ficheiro irá expirar depois de 1 transferência ou em 24 horas.
expireInfo = A ligação para o seu ficheiro irá expirar depois de { $downloadCount } or { $timespan }.
downloadCount = { $num ->
downloadCount =
{ $num ->
[one] 1 transferência
*[other] { $num } transferências
}

View File

@@ -1,13 +1,13 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = un experiment web
siteFeedback = Feedback
uploadPageHeader = Partajare de fișiere privată și criptată
uploadPageExplainer = Trimite fișiere printr-un link sigur, privat și criptat care expiră automat pentru ca informațiile să rămână în siguranță.
uploadPageExplainer = Trimite fișiere printr-un link sigur, privat și criptat care expiră automat pentru a te asigura că lucrurile tale nu rămân online pentru totdeauna.
uploadPageLearnMore = Află mai multe
uploadPageDropMessage = Aruncă fișierul aici pentru a începe încărcarea.
uploadPageDropMessage = Trage fișierul aici pentru a începe încărcarea
uploadPageSizeMessage = Pentru a lucra mai ușor, recomandăm să păstrezi fișierul sub 1GB
uploadPageBrowseButton = Alege un fișier din calculator.
uploadPageBrowseButton = Selectează un fișier din calculator
uploadPageBrowseButton1 = Selectează un fișier pentru încărcare
uploadPageMultipleFilesAlert = Încărcarea mai multor fișiere deodată sau a dosarelor nu este suportată.
uploadPageBrowseButtonTitle = Încarcă fișier
@@ -17,47 +17,55 @@ verifyingFile = Se verifică...
encryptingFile = Se criptează…
decryptingFile = Se decriptează…
notifyUploadDone = Încărcarea s-a finalizat.
uploadingPageMessage = După ce fișierul tău este încărcat vei putea seta opțiuni de expirare.
uploadingPageCancel = Anulează încărcarea
uploadCancelNotification = Încărcarea a fost anulată.
uploadingPageLargeFileMessage = Stai calm! Acest fișier este mare. S-ar putea să dureze un timp încărcarea.
uploadingFileNotification = Notifică-mă când încărcarea este încheiată.
uploadSuccessConfirmHeader = Pregătit pentru trimitere
uploadSvgAlt = Încarcă
uploadSuccessTimingHeader = Linkul către fișierul tău va expira după 1 descărcare sau în 24 de ore.
expireInfo = Linkul la fișier va expira după { $downloadCount } sau { $timespan }.
timespanHours = { $num ->
[one] 1 oră
[few] ore
*[other] de ore
uploadSuccessTimingHeader = Linkul către fișier va expira după 1 descărcare sau în 24 de ore.
expireInfo = Linkul către fișier va expira după { $downloadCount } sau { $timespan }.
downloadCount =
{ $num ->
[one] 1 descărcare
[few] { $num } descărcări
*[other] { $num } de descărcări
}
copyUrlFormLabelWithName = Copiază și împărtășește linkul de la fișierul de trimis: { $filename }
timespanHours =
{ $num ->
[one] 1 oră
[few] { $num } ore
*[other] { $num } de ore
}
copyUrlFormLabelWithName = Copiază și împărtășește linkul pentru a trimite fișierul: { $filename }
copyUrlFormButton = Copiază în clipboard
copiedUrl = Copiat!
deleteFileButton = Șterge fișierul
sendAnotherFileLink = Trimite un alt fișier
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = Descarcă
downloadsFileList = Descărcări
// Used as header in a column indicating the amount of time left before a
// download link expires (e.g. "10h 5m")
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = Timp
// Used as header in a column indicating the number of times a file has been
// downloaded
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = Descarcă { $filename }
downloadFileSize = ({ $size })
unlockInputLabel = Introdu parola
unlockInputPlaceholder = Parolă
unlockButtonLabel = Deblochează
downloadFileTitle = Descarcă fișierul criptat
// Firefox Send is a brand name and should not be localized.
downloadMessage = Un prieten îți trimite un fișier prin Firefox Send, un serviciu care îți permite să împărtășești un fișier printr-un link sigur, privat și criptat care expiră automat pentru a păstra informațiile tale online doar temporar.
// Text and title used on the download link/button (indicates an action).
# Firefox Send is a brand name and should not be localized.
downloadMessage = Un prieten îți trimite un fișier prin Firefox Send, un serviciu care îți permite să împărtășești un fișier printr-un link sigur, privat și criptat care expiră automat pentru a te asigura că lucrurile tale nu rămân online pentru totdeauna.
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Descarcă
downloadNotification = Descărcarea s-a încheiat.
downloadFinish = Descărcare încheiată
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } din { $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Încearcă Firefox Send
downloadingPageProgress = Se descarcă { $filename } ({ $size })
downloadingPageMessage = Te rugăm să păstrezi această file deschisă în timp ce preluăm fișierul și îl decriptăm.
@@ -65,32 +73,32 @@ errorAltText = Eroare la încărcare
errorPageHeader = Ceva a mers prost!
errorPageMessage = A apărut o eroare la încărcarea fișierului.
errorPageLink = Trimite un alt fișier
fileTooBig = Acest fișier este prea mare. Trebuie să fie sub { $size }.
fileTooBig = Acest fișier este prea mare. Ar trebuie să fie sub { $size }.
linkExpiredAlt = Link expirat
expiredPageHeader = Acest link a expirat sau nu a existat de la bun început!
notSupportedHeader = Browserul tău nu este suportat.
// Firefox Send is a brand name and should not be localized.
notSupportedDetail = Din păcate acest browser nu suportă tehnologii web precum Firefox Send. Trebuie să încerci alt browser. Îți recomandăm Firefox!
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = Din păcate, acest browser nu suportă tehnologiile web folosite de Firefox Send. Va trebui să încerci un alt browser. Îți recomandăm Firefox!
notSupportedLink = De ce browserul meu nu este suportat?
notSupportedOutdatedDetail = Din păcate această versiune de Firefox nu suportă tehnologiile web din spatele Firefox Sent. Îți recomandăm să actualizezi browserul.
notSupportedOutdatedDetail = Din păcate această versiune de Firefox nu suportă tehnologiile web din spatele Firefox Sent. Va trebui să actualizezi browserul.
updateFirefox = Actualizează Firefox
downloadFirefoxButtonSub = Descărcare gratuită
uploadedFile = Fișier
copyFileList = Copiază URL-ul
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = Expiră în
deleteFileList = Șterge
nevermindButton = Uită
legalHeader = Termeni de utilizare și politica de confidențialitate
legalNoticeTestPilot = Firefox Send este momentan un experiment Test Pilot și supus <a>Termenilor de utilizare</a> Test Pilot și a <a>Politicii de confidențialitate</a>. Poți afla mai multe despre acest experiment <a>aici</a>.
legalNoticeMozilla = Folosirea site-ului Firefox Send mai este supusă <a>Politicii de confidențialitate pentru site-uri web</a> și a <a>Termenilor de folosire a site-urilor web</a>.
legalNoticeTestPilot = Firefox Send este în prezent un experiment Test Pilot și supus <a>Termenilor de utilizare a serviciului</a> și a <a>Politicii de confidențialitate</a> Test Pilot. Poți afla mai multe despre acest experiment și colectarea sa de date <a>aici</a>.
legalNoticeMozilla = Folosirea site-ului Firefox Send mai este supusă <a>Politicii de confidențialitate pentru site-uri web</a> și a <a>Termenilor de utilizare a site-urilor web</a>.
deletePopupText = Ștergi aceast fișier?
deletePopupYes = Da
deletePopupCancel = Renunță
deleteButtonHover = Șterge
copyUrlHover = Copiază URL-ul
footerLinkLegal = Mențiuni legale
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Despre Test Pilot
footerLinkPrivacy = Confidențialitate
footerLinkTerms = Termeni
@@ -99,6 +107,17 @@ requirePasswordCheckbox = Este necesară o parolă pentru a descărca acest fiș
addPasswordButton = Adaugă parolă
changePasswordButton = Modifică
passwordTryAgain = Parola este incorectă. Încearcă din nou.
// This label is followed by the password needed to download a file
passwordResult = Parola: { $password }
reportIPInfringement = Raportează încălcarea proprietății intelectuale
javascriptRequired = Firefox Send are nevoie de JavaScript
whyJavascript = De ce are nevoie Firefox Send de JavaScript?
enableJavascript = Te rugăm să reactivezi JavaScript și să încerci din nou.
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours }h { $minutes }m
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes } m
# A short status message shown when a password is successfully set
passwordIsSet = Parola a fost setată
# A short status message shown when the user enters a long password
maxPasswordLength = Lungime minimă a parolei: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = Această parolă nu a putut fi setată

View File

@@ -26,15 +26,17 @@ uploadSuccessConfirmHeader = Готов к отправке
uploadSvgAlt = Загрузить
uploadSuccessTimingHeader = Ссылка на ваш файл станет недоступна после 1 загрузки файла или через 24 часа.
expireInfo = Ссылка на ваш файл станет недоступна после { $downloadCount } файла или через { $timespan }.
downloadCount = { $num ->
[one] { $number } загрузки
[few] { $number } загрузок
*[other] { $number } загрузок
downloadCount =
{ $num ->
[one] { $num } загрузка
[few] { $num } загрузки
*[other] { $num } загрузок
}
timespanHours = { $num ->
[one] { $number } час
[few] { $number } часа
*[other] { $number } часов
timespanHours =
{ $num ->
[one] { $num } час
[few] { $num } часа
*[other] { $num } часов
}
copyUrlFormLabelWithName = Скопировать и поделиться ссылкой на отправку вашего файла: { $filename }
copyUrlFormButton = Скопировать в буфер обмена

View File

@@ -107,8 +107,6 @@ requirePasswordCheckbox = Zahtevaj geslo za prenos te datoteke
addPasswordButton = Dodaj geslo
changePasswordButton = Spremeni
passwordTryAgain = Napačno geslo. Poskusite znova.
# This label is followed by the password needed to download a file
passwordResult = Geslo: { $password }
reportIPInfringement = Prijavite kršitev naslova IP
javascriptRequired = Firefox Send zahteva JavaScript
whyJavascript = Zakaj Firefox Send zahteva JavaScript?
@@ -119,3 +117,7 @@ expiresHoursMinutes = { $hours }h { $minutes }m
expiresMinutes = { $minutes }m
# A short status message shown when a password is successfully set
passwordIsSet = Geslo je nastavljeno
# A short status message shown when the user enters a long password
maxPasswordLength = Največja dolžina gesla: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = Gesla ni mogoče nastaviti

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = జాల ప్రయోగం
siteFeedback = అభిప్రాయం
@@ -22,25 +22,42 @@ uploadingFileNotification = ఎగుమతి పూర్తయినప్ప
uploadSuccessConfirmHeader = పంపించడానికి సిద్ధంగా ఉంది
uploadSvgAlt = ఎగుమతి చేయండి
uploadSuccessTimingHeader = మీ ఫైలు లంకె గడువు 1 దిగుమతి తరువాత లేదా 24 గంటల తరువాత ముగుస్తుంది.
expireInfo = మీ ఫైలుకు లంకె { $downloadCount } లేదా { $timespan } తర్వాత గడువు అవుతుంది.
downloadCount =
{ $num ->
[one] 1 దింపుకోలు
*[other] { $num } దింపుకోళ్ళు
}
timespanHours =
{ $num ->
[one] 1 గంట
*[other] { $num } గంటలు
}
copyUrlFormLabelWithName = మీ ఫైల్ను పంపడానికి లంకెను నకలు చేయండి మరియు పంచండి: { $filename }
copyUrlFormButton = క్లిప్బోర్డ్కు నకలు చేయండి
copiedUrl = నకలు చేయబడింది!
deleteFileButton = ఫైలును తొలగించండి
sendAnotherFileLink = మరో ఫైలును పంపండి
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = దిగుమతి
downloadsFileList = దింపుకోళ్ళు
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = సమయం
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = దిగుమతి { $filename }
downloadFileSize = ({ $size })
unlockInputLabel = సంకేతపదాన్ని తెలపండి
unlockInputPlaceholder = సంకేతపదం
unlockButtonLabel = తాళం తీయి
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = దిగుమతి
downloadNotification = మీ దిగుమతి పూర్తయ్యింది.
downloadFinish = దిగుమతి పూర్తయింది
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = { $totalSize }) యొక్క ({ $partialSize }
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Firefox sendను ప్రయత్నించండి
downloadingPageProgress = దిగుమతిచేస్తున్నది { $filename } ({ $size })
errorAltText = ఎగుమతిలో లోపం
@@ -56,7 +73,7 @@ updateFirefox = Firefoxను నవీకరించు
downloadFirefoxButtonSub = ఉచిత దిగుమతులు
uploadedFile = దస్త్రం
copyFileList = URL నకలుతీయి
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = ఇంతలో గడువుతీరును
deleteFileList = తొలగించు
nevermindButton = పర్వాలేదు
@@ -67,13 +84,26 @@ deletePopupCancel = రద్దుచేయి
deleteButtonHover = తొలగించు
copyUrlHover = URLను నకలు చేయండి
footerLinkLegal = చట్టపరమైన
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = టెస్ట్ పైలట్ గురించి
footerLinkPrivacy = గోప్యత
footerLinkTerms = నియమాలు
footerLinkCookies = కుకీలు
requirePasswordCheckbox = ఈ ఫైల్ను దింపుకోటానికి సంకేతపదం అవసరం
addPasswordButton = సంకేతపదం జోడించండి
changePasswordButton = మార్చు
passwordTryAgain = సరికాని సంకేతపదం. మళ్ళీ ప్రయత్నించండి.
// This label is followed by the password needed to download a file
passwordResult = సంకేతపదం: { $password }
reportIPInfringement = మేధో సంపత్తి హక్కుల ఉల్లంఘనను నివేదించండి
javascriptRequired = Firefox Sendకి జావాస్క్రిప్టు కావాలి
whyJavascript = Firefox Sendకి జావాస్క్రిప్టు ఎందుకు కావాలి?
enableJavascript = జావాస్క్రిప్టు చేతనంచేసి మళ్ళీ ప్రయత్నించండి.
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours }గం { $minutes }ని
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes }ని
# A short status message shown when a password is successfully set
passwordIsSet = సంకేతపదం అమరింది
# A short status message shown when the user enters a long password
maxPasswordLength = సంకేతపదం గరిష్ఠ పొడవు: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = ఈ సంకేతపదం పెట్టలేకపోయాం

View File

@@ -102,8 +102,6 @@ requirePasswordCheckbox = Mangailangan ng isang password upang i-download ang fi
addPasswordButton = Magdagdag ng password
changePasswordButton = Palitan
passwordTryAgain = Maling password. Subukan muli.
# This label is followed by the password needed to download a file
passwordResult = Password: { $password }
reportIPInfringement = Report IP Infringement
javascriptRequired = Nangangailangan ang JavaScript sa JavaScript
whyJavascript = Bakit ang JavaScript ay nangangailangan ng JavaScript?
@@ -114,3 +112,7 @@ expiresHoursMinutes = { $hours }h { $minutes }m
expiresMinutes = { $minutes }m
# A short status message shown when a password is successfully set
passwordIsSet = I-set ang password
# A short status message shown when the user enters a long password
maxPasswordLength = Pinakamataas na haba ng password: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = Hindi maitakda ang password na ito

View File

@@ -27,8 +27,10 @@ uploadSvgAlt = Yükle
uploadSuccessTimingHeader = Dosyanız 1 kez indirildikten veya 24 saat geçtikten sonra linkiniz geçersiz olacaktır.
expireInfo = Dosyanızın bağlantısı { $downloadCount } sonra veya { $timespan } zaman aşımına uğrayacaktır.
downloadCount = { $num } indirme
timespanHours = { $num ->
*[one] { $num } saat
timespanHours =
{ $num ->
[one] 1 saat
*[other] { $num } saat
}
copyUrlFormLabelWithName = { $filename } dosyanızı başkasına göndermek için aşağıdaki linki kopyalayın.
copyUrlFormButton = Panoya kopyala

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = веб-експеримент
siteFeedback = Відгуки
@@ -41,23 +41,29 @@ copyUrlFormButton = Копіювати у буфер обміну
copiedUrl = Скопійовано!
deleteFileButton = Видалити файл
sendAnotherFileLink = Надіслати інший файл
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = Завантаживи
downloadsFileList = Завантажень
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = Дійсний
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = Завантажити { $filename }
downloadFileSize = ({ $size })
unlockInputLabel = Введіть пароль
unlockInputPlaceholder = Пароль
unlockButtonLabel = Розблокувати
downloadFileTitle = Завантажити зашифрований файл
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
downloadMessage = Ваш друг надіслав файл за допомогою Firefox Send, який дозволяє ділитися файлами, використовуючи безпечні, приватні та зашифровані посилання, термін дії яких автоматично закінчується, щоб ваші файли не лишилися в Інтернеті назавжди.
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Завантажити
downloadNotification = Ваше завантаження готово.
downloadFinish = Завантаження готово
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } з { $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Спробуйте Firefox Send
downloadingPageProgress = Завантаження { $filename } ({ $size })
downloadingPageMessage = Будь ласка, залиште цю вкладку відкритою, поки ми завантажуємо ваш файл і розшифровуємо його.
@@ -69,7 +75,7 @@ fileTooBig = Цей файл завеликий для вивантаження.
linkExpiredAlt = Час дії посилання минув
expiredPageHeader = Посилання не існує, або час його дії минув!
notSupportedHeader = Ваш браузер не підтримується.
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = На жаль, цей браузер не підтримує веб-технологію, завдяки якій працює Firefox Send. Вам треба скористатися іншим браузером. Ми рекомендуємо Firefox!
notSupportedLink = Чому мій браузер не підтримується?
notSupportedOutdatedDetail = На жаль, ця версія Firefox не підтримує веб-технологію, завдяки якій працює Firefox Send. Вам потрібно оновити свій браузер.
@@ -77,7 +83,7 @@ updateFirefox = Оновити Firefox
downloadFirefoxButtonSub = Безкоштовне завантаження
uploadedFile = Файл
copyFileList = Копіювати URL
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = Термін дії закінчується
deleteFileList = Видалити
nevermindButton = Не важливо
@@ -90,14 +96,26 @@ deletePopupCancel = Скасувати
deleteButtonHover = Видалити
copyUrlHover = Копіювати URL
footerLinkLegal = Права
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Про Test Pilot
footerLinkPrivacy = Приватність
footerLinkTerms = Умови
footerLinkCookies = Куки
requirePasswordCheckbox = Вимагати пароль для завантаження цього файлу
addPasswordButton = Додати пароль
changePasswordButton = Змінити
passwordTryAgain = Невірний пароль. Спробуйте знову.
// This label is followed by the password needed to download a file
passwordResult = Пароль: { $password }
reportIPInfringement = Повідомити про порушення прав на інтелектуальну власність
javascriptRequired = Firefox Send потребує JavaScript
whyJavascript = Чому для Firefox Send потрібен JavaScript?
enableJavascript = Будь ласка, увімкніть JavaScript та спробуйте знову.
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours } год. { $minutes } хв.
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes } хв.
# A short status message shown when a password is successfully set
passwordIsSet = Пароль встановлено
# A short status message shown when the user enters a long password
maxPasswordLength = Найбільша довжина паролю: { $length }
# A short status message shown when there was an error setting the password
passwordSetError = Неможливо встановити цей пароль

View File

@@ -1,4 +1,4 @@
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = Thử nghiệm trên web
siteFeedback = Phản hồi
@@ -25,24 +25,41 @@ uploadingFileNotification = Thông báo cho tôi khi tải lên hoàn tất.
uploadSuccessConfirmHeader = Đã sẵn sàng để Gửi
uploadSvgAlt = Tải lên
uploadSuccessTimingHeader = Liên kết đến tập tin của bạn sẽ hết hạn sau 1 lượt tải về hoặc trong 24 giờ.
downloadCount =
{ $num ->
*[other] lượt tải
}
timespanHours =
{ $num ->
*[other] giờ
}
copyUrlFormLabelWithName = Sao chép và chia sẻ liên kết để gửi tập tin của bạn: { $filename }
copyUrlFormButton = Sao chép vào vùng nhớ tạm
copiedUrl = Đã sao chép!
deleteFileButton = Xóa tập tin
sendAnotherFileLink = Gửi tập tin khác
// Alternative text used on the download link/button (indicates an action).
# Alternative text used on the download link/button (indicates an action).
downloadAltText = Tải về
# Used as header in a column indicating the amount of time left before a
# download link expires (e.g. "10h 5m")
timeFileList = Thời gian
# Used as header in a column indicating the number of times a file has been
# downloaded
downloadFileName = Tải về { $filename }
downloadFileSize = ({ $size })
// Firefox Send is a brand name and should not be localized.
unlockInputLabel = Nhập mật khẩu
unlockInputPlaceholder = Mật khẩu
unlockButtonLabel = Mở khóa
downloadFileTitle = Tải về tập tin được mã hóa
# Firefox Send is a brand name and should not be localized.
downloadMessage = Bạn của bạn đang gửi một tập tin thông qua Firefox Send, một dịch vụ cho phép bạn chia sẻ tập tin một cách an toàn, riêng tư, có liên kết được mã hóa và sẽ tự động hết hạn để chắc chắn rằng dữ liệu của bạn không nằm mãi mãi trên Internet.
// Text and title used on the download link/button (indicates an action).
# Text and title used on the download link/button (indicates an action).
downloadButtonLabel = Tải về
downloadNotification = Quá trình tải về đã hoàn tất.
downloadFinish = Tải về hoàn tất
// This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
# This message is displayed when uploading or downloading a file, e.g. "(1,3 MB of 10 MB)".
fileSizeProgress = ({ $partialSize } trong { $totalSize })
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
sendYourFilesLink = Dùng thử Firefox Send
downloadingPageProgress = Đang tải về { $filename } ({ $size })
downloadingPageMessage = Vui lòng giữ cửa sổ này mở trong khi chúng tôi lấy tập tin và giải mã chúng.
@@ -54,7 +71,7 @@ fileTooBig = Tập tin này quá lớn để tải lên. Kích thước tập ti
linkExpiredAlt = Liên kết đã hết hạn
expiredPageHeader = Liên kết này đã hết hạn hoặc chưa từng được sử dụng!
notSupportedHeader = Trình duyệt của bạn không được hỗ trợ.
// Firefox Send is a brand name and should not be localized.
# Firefox Send is a brand name and should not be localized.
notSupportedDetail = Thật không may trình duyệt này không hỗ trợ công nghệ đã tạo nên Firefox Send. Bạn cần thử với trình duyệt khác. Chúng tôi khuyên dùng Firefox!
notSupportedLink = Tại sao trình duyệt của tôi không được hỗ trợ?
notSupportedOutdatedDetail = Thật không may là phiên bản Firefox này không hỗ trợ công nghệ được sử dụng trong Firefox Send. Bạn cần cập nhật trình duyệt của bạn.
@@ -62,7 +79,7 @@ updateFirefox = Cập nhật Firefox
downloadFirefoxButtonSub = Tải về miễn phí
uploadedFile = Tập tin
copyFileList = Sao chép URL
// expiryFileList is used as a column header
# expiryFileList is used as a column header
expiryFileList = Hết hạn trong
deleteFileList = Xóa
nevermindButton = Đừng bận tâm
@@ -75,8 +92,23 @@ deletePopupCancel = Hủy bỏ
deleteButtonHover = Xóa
copyUrlHover = Sao chép URL
footerLinkLegal = Pháp lý
// Test Pilot is a proper name and should not be localized.
# Test Pilot is a proper name and should not be localized.
footerLinkAbout = Về Test Pilot
footerLinkPrivacy = Quyền riêng tư
footerLinkTerms = Điều khoản
footerLinkCookies = Cookies
requirePasswordCheckbox = Yêu cầu mật khẩu khi tải về tập tin này
addPasswordButton = Thêm mật khẩu
passwordTryAgain = Sai mật khẩu. Vui lòng thử lại.
reportIPInfringement = Báo cáo vi phạm
javascriptRequired = Firefox Send cần JavaScript
whyJavascript = Tại sao Firefox Send cần JavaScript?
enableJavascript = Vui lòng kích hoạt JavaScript và thử lại.
# A short representation of a countdown timer containing the number of hours and minutes remaining as digits, example "13h 47m"
expiresHoursMinutes = { $hours } giờ { $minutes } phút
# A short representation of a countdown timer containing the number of minutes remaining as digits, example "56m"
expiresMinutes = { $minutes } phút
# A short status message shown when a password is successfully set
passwordIsSet = Đã đặt mật khẩu
# A short status message shown when the user enters a long password
maxPasswordLength = Độ dài mật khẩu tối đa: { $length }

View File

@@ -69,6 +69,7 @@ module.exports = function(state, body = '') {
<script defer src="${assets.get('runtime.js')}"></script>
<script defer src="${assets.get('vendor.js')}"></script>
<script defer src="${locales.get(state.locale)}"></script>
<script defer src="${assets.get('cryptofill.js')}"></script>
<script defer src="${assets.get('app.js')}"></script>
</head>
${body}

View File

@@ -4,6 +4,10 @@ const fs = require('fs');
const path = require('path');
const { negotiateLanguages } = require('fluent-langneg');
const langData = require('cldr-core/supplemental/likelySubtags.json');
// We return early in the middleware if the lang header is long.
// If that ever changes we should re-evaluate this regex.
// eslint-disable-next-line security/detect-unsafe-regex
const acceptLanguages = /(([a-zA-Z]+(-[a-zA-Z0-9]+){0,2})|\*)(;q=[0-1](\.[0-9]+)?)?/g;
function allLangs() {

19
server/readme.md Normal file
View File

@@ -0,0 +1,19 @@
# Server Code
The server provides the API, serves static assets, and renders the pages for Send. The production entrypoint is [prod.js](./prod.js) and the development entrypoint is [dev.js](./dev.js) via `webpack-dev-server`.
## Server configuration
[config.js](./config.js) contains the schema for our configuration options. Environment variables are the preferred method for setting configuration.
## Middleware
Contains authentication and localization middleware.
## Routes
Contains all the server routes and handlers for the API and pages
## Storage
Contains implementations of possible storage engines for the files and metadata

View File

@@ -7,10 +7,10 @@ function kv(f) {
module.exports = function() {
const files = fs.readdirSync(path.join(__dirname, 'tests'));
const code = files.map(kv).join(';\n');
const code = "require('fast-text-encoding');\n" + files.map(kv).join(';\n');
return {
code,
dependencies: files.map(f => require.resolve('./tests/' + f)),
cacheable: false
cacheable: true
};
};

View File

@@ -29,6 +29,7 @@ module.exports = function(app) {
})
</script>
<script src="/jsconfig.js"></script>
<script src="${assets.get('cryptofill.js')}"></script>
<script src="${assets.get('runtime.js')}"></script>
<script src="${assets.get('vendor.js')}"></script>
<script src="${assets.get('tests.js')}"></script>

View File

@@ -0,0 +1,122 @@
import assert from 'assert';
import { arrayToB64, b64ToArray } from '../../../app/utils';
describe('webcrypto', function() {
it('can do it', async function() {
const encoder = new TextEncoder();
const x = b64ToArray('SPIfAlwbnncIFw3hEHYihw');
const a = await crypto.subtle.importKey('raw', x, 'PBKDF2', false, [
'deriveKey'
]);
const ad = await crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: encoder.encode('metadata'),
iterations: 100,
hash: 'SHA-256'
},
a,
{
name: 'AES-GCM',
length: 128
},
false,
['encrypt', 'decrypt']
);
const ae = await crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: new Uint8Array(12),
tagLength: 128
},
ad,
encoder.encode('hello world!')
);
assert.equal(
arrayToB64(new Uint8Array(ae)),
'UXQQ4yVf55TRk9AZtz5QCwFofRvh-HdWJyxSCQ'
);
const ah = await crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: encoder.encode('authentication'),
iterations: 100,
hash: 'SHA-256'
},
a,
{
name: 'HMAC',
hash: { name: 'SHA-256' }
},
true,
['sign']
);
const ahx = await crypto.subtle.exportKey('raw', ah);
assert.equal(
arrayToB64(new Uint8Array(ahx)),
'wxXDmHgmMgrcDVD8zbDLRl2yNa8jSAQgsaeIBZ4vueygpxzaTK6ZE_6X-XHvllBly6pSuFNbSxcve0ZHhVdcEA'
);
// const jwk = await crypto.subtle.exportKey('jwk', ah)
// console.error(jwk)
const as = await crypto.subtle.sign(
{
name: 'HMAC'
},
ah,
encoder.encode('test')
);
assert.equal(
arrayToB64(new Uint8Array(as)),
'AOi4HcoCJxQ4nUYxlmHB1rlcxQBn-zVjrSHz-VW7S-I'
);
const b = await crypto.subtle.importKey('raw', x, 'HKDF', false, [
'deriveKey'
]);
const bd = await crypto.subtle.deriveKey(
{
name: 'HKDF',
salt: new Uint8Array(),
info: encoder.encode('encryption'),
hash: 'SHA-256'
},
b,
{
name: 'AES-GCM',
length: 128
},
true,
['encrypt', 'decrypt']
);
const bdx = await crypto.subtle.exportKey('raw', bd);
assert.equal(arrayToB64(new Uint8Array(bdx)), 'g7okjWWO9yueDz16-owShQ');
const bh = await crypto.subtle.deriveKey(
{
name: 'HKDF',
salt: new Uint8Array(),
info: encoder.encode('authentication'),
hash: 'SHA-256'
},
b,
{
name: 'HMAC',
hash: { name: 'SHA-256' }
},
true,
['sign']
);
const bhx = await crypto.subtle.exportKey('raw', bh);
assert.equal(
arrayToB64(new Uint8Array(bhx)),
'TQOGtmQ8-ZfnWu6Iq-U1IAVBVREFuI17xqsW1shiC8eMCa-a5qeYTvoX3-5kCoCha8R59ycnPDnTz75clLBmbQ'
);
});
});

View File

@@ -0,0 +1,10 @@
FROM ubuntu:xenial
RUN apt-get update && \
apt-get install -y python-pip python-dev && \
pip install tox
COPY . /integration
WORKDIR /integration
RUN tox --notest
CMD ["tox", "-e", "integration-tests"]

View File

@@ -0,0 +1,66 @@
# Integration Tests for [Firefox Send](https://send.firefox.com/).
## How to run the tests locally
### Clone the repository
If you have cloned this project already then you can skip this, otherwise you'll
need to clone this repo using Git. If you do not know how to clone a GitHub
repository, check out this [help page][git-clone] from GitHub.
If you think you would like to contribute to the tests by writing or maintaining
them in the future, it would be a good idea to create a fork of this repository
first, and then clone that. GitHub also has great instructions for
[forking a repository][git-fork].
### App Setup
Please view the README at the root directory of the project.
### Run the tests
Included in the docker-compose file is an image containing Firefox Nightly.
[tox][Tox] is our test environment manager and [pytest][pytest] is the test runner.
To run the tests, execute the commands below:
```sh
npm run build
npm run test-integration
```
### Adding a test
The tests are written in Python using a POM, or Page Object Model. The plugin we use for this is called [pypom][pypom]. Please read the documentation there for good examples on how to use the Page Object Model when writing tests.
The pytest plugin that we use for running tests has a number of advanced command line options available too. The full documentation for the plugin can be found [here][pytest-selenium].
### Watching a test run (within the docker container)
The tests are run on a live version of Firefox, but they are run headless. To access the container where the tests are run to view them follow these steps:
1. Make sure all of the containers are running:
```sh
docker-compose ps
```
If not start them detached:
```sh
docker-compose up -d
```
2. Open your favorite VNC viewer and type in `localhost:5900`.
3. The password is ```secret```.
4. The viewer should open a window with a Ubuntu logo. If that happens you are connected to the ```selenium-firefox``` image and if you start the test, you should see a Firefox window open and the tests running.
### Debugging a failure
Whether a test passes or fails will result in a HTML report being created. This report will have detailed information of the test run and if a test does fail, it will provide geckodriver logs, terminal logs, as well as a screenshot of the browser when the test failed. We use a pytest plugin called [pytest-html][pytest-html] to create this report. The report can be found at ```coverage/send-test.html```. It should be viewed within a browser.
[flake8]: http://flake8.pycqa.org/en/latest/
[git-clone]: https://help.github.com/articles/cloning-a-repository/
[git-fork]: https://help.github.com/articles/fork-a-repo/
[geckodriver]: https://github.com/mozilla/geckodriver/releases/tag/v0.19.1
[pypom]: http://pypom.readthedocs.io/en/latest/
[pytest]: https://docs.pytest.org/en/latest/
[pytest-html]: https://github.com/pytest-dev/pytest-html
[pytest-selenium]: http://pytest-selenium.readthedocs.org/
[Selenium]: http://selenium-python.readthedocs.io/index.html
[selenium-api]: http://selenium-python.readthedocs.io/locating-elements.html
[Tox]: http://tox.readthedocs.io/

View File

@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
"""Configuration files for pytest."""
import pytest
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
from pages.desktop.download import Download
from pages.desktop.home import Home
@pytest.fixture
def firefox_options(firefox_options, download_location_dir):
"""Firefox options."""
firefox_options.set_preference("browser.download.panel.shown", False)
firefox_options.set_preference(
"browser.helperApps.neverAsk.openFile", "text/plain")
firefox_options.set_preference(
"browser.helperApps.neverAsk.saveToDisk", "text/plain")
firefox_options.set_preference("browser.download.folderList", 2)
firefox_options.set_preference(
"browser.download.dir", "{0}".format(download_location_dir))
firefox_options.add_argument('-foreground')
firefox_options.log.level = 'trace'
return firefox_options
@pytest.fixture(scope='session', autouse=True)
def _verify_url(request, base_url):
"""Verifies the base URL"""
verify = request.config.option.verify_base_url
if base_url and verify:
session = requests.Session()
retries = Retry(backoff_factor=0.1,
status_forcelist=[500, 502, 503, 504])
session.mount(base_url, HTTPAdapter(max_retries=retries))
session.get(base_url, verify=False)
@pytest.fixture
def download_location_dir(tmpdir):
"""Directory for downloading sample file."""
return tmpdir.mkdir('test_download')
@pytest.fixture
def upload_location_dir(tmpdir):
"""Directory for uploading sample file."""
return tmpdir.mkdir('test_upload')
@pytest.fixture
def test_file(upload_location_dir):
"""Create test upload/download file."""
setattr(test_file, 'name', 'sample.txt')
setattr(test_file, 'location', upload_location_dir.join(test_file.name))
return test_file
@pytest.fixture
def download_file(upload_file):
"""Uploads and downloads a file"""
download = Download(upload_file.selenium, upload_file.file_url).open()
download.download_btn.click()
return download
@pytest.fixture
def upload_file(selenium, base_url, download_location_dir, test_file):
"""Upload file fixture."""
home = Home(selenium, base_url).open()
test_file.location.write('This is a test! This is a test!')
return home.upload_area("{0}".format(test_file.location.realpath()))

View File

View File

@@ -0,0 +1,41 @@
from pypom import Page, Region
from selenium.webdriver.common.by import By
class Base(Page):
"""Base object model."""
_url = '{base_url}'
_send_logo_locator = (By.CLASS_NAME, 'logo')
def __init__(self, selenium, base_url, locale='en-US', **kwargs):
super(Base, self).__init__(
selenium, base_url, locale=locale, timeout=20, **kwargs)
def wait_for_page_to_load(self):
self.wait.until(
lambda _: self.find_element(
*self._send_logo_locator).is_displayed())
return self
@property
def footer(self):
return self.Footer(self)
class Footer(Region):
_root_element = (By.CLASS_NAME, 'footer')
_legal_links = (By.CLASS_NAME, 'legalSection__link')
@property
def links(self):
return [self.Links(self, el) for el in self.find_elements(
*self._legal_links)]
class Links(Region):
@property
def name(self):
return self.root.text.split()[0]
def click(self):
self.root.click()

View File

@@ -0,0 +1,17 @@
from selenium.webdriver.common.by import By
from pages.desktop.base import Base
class Download(Base):
"""Download page object model."""
_download_button_locator = (By.CLASS_NAME, 'btn--download')
def wait_for_page_to_load(self):
self.wait.until(lambda _: self.download_btn.is_displayed())
@property
def download_btn(self):
"""Download button."""
return self.find_element(*self._download_button_locator)

View File

@@ -0,0 +1,26 @@
from selenium.webdriver.common.by import By
from pages.desktop.base import Base
class Home(Base):
"""Firefox Send Home page object model."""
_upload_area_locator = (By.ID, 'file-upload')
_upload_button_locator = (By.CLASS_NAME, 'btn--file')
@property
def upload_btn(self):
"""Upload button."""
return self.find_element(*self._upload_button_locator)
def upload_area(self, path, cancel=False):
"""Area that allows for drag and drop uploading.
Returns Progress Object.
"""
self.find_element(*self._upload_area_locator).send_keys(path)
from pages.desktop.progress import Progress
return Progress(
self.selenium, self.base_url).wait_for_page_to_load(
cancel_after_load=cancel)

View File

@@ -0,0 +1,25 @@
from selenium.webdriver.common.by import By
from pages.desktop.base import Base
class Progress(Base):
"""Progress page object model."""
_cancel_button = (By.ID, 'cancel-upload')
_progress_icon_locator = (By.CLASS_NAME, 'progress__bar')
def wait_for_page_to_load(self, cancel_after_load=False):
self.wait.until(
lambda _: self.find_element(
*self._progress_icon_locator).is_displayed())
if cancel_after_load:
self.cancel_btn.click()
return
from pages.desktop.share import Share
return Share(self.selenium, self.base_url).wait_for_page_to_load()
@property
def cancel_btn(self):
"""Cancel upload button."""
return self.find_element(*self._cancel_button)

View File

@@ -0,0 +1,22 @@
from selenium.webdriver.common.by import By
from pages.desktop.base import Base
class Share(Base):
"""SHare page object model."""
_share_page_locator = (By.CLASS_NAME, 'sharePage')
_share_url_locator = (By.ID, 'fileUrl')
def wait_for_page_to_load(self):
self.wait.until(
lambda _: self.find_element(
*self._share_page_locator).is_displayed())
return self
@property
def file_url(self):
"""File uploaded URL."""
return self.find_element(
*self._share_url_locator).get_property('value')

View File

@@ -0,0 +1,8 @@
selenium==3.12.0
flake8==3.5.0
flake8-isort==2.5
PyPOM==2.0.0
pytest==3.5.1
pytest-html==1.17.0
pytest-selenium==1.12.0
pytest-xdist==1.22.2

View File

@@ -0,0 +1,6 @@
"""Test files regarding downloads."""
def test_download(download_file, download_location_dir, test_file):
"""Test downloaded file matches uploaded file."""
assert download_location_dir.ensure(test_file.name)

View File

@@ -0,0 +1,14 @@
import pytest
from pages.desktop.base import Base
footer_links = ['mozilla', 'mozilla', 'about', 'legal', 'legal', 'cookies',
'report-infringement']
@pytest.mark.parametrize('i, name', enumerate(footer_links))
def test_legal_links(selenium, base_url, i, name):
"""Test links in footer load correct pages."""
page = Base(selenium, base_url).open()
page.footer.links[i].click()
assert name in selenium.current_url

View File

@@ -0,0 +1,6 @@
"""Test files regarding the upload progress pages."""
def test_progress(upload_file):
"""Test progress icon shows while uploading."""
assert upload_file

View File

@@ -0,0 +1,6 @@
"""Test files regarding uploading."""
def test_upload(upload_file):
"""Test file upload and creates URL."""
assert upload_file.file_url is not None

19
test/integration/tox.ini Executable file
View File

@@ -0,0 +1,19 @@
[tox]
envlist = integration-tests, flake8
skipsdist = True
[testenv]
skip_install = True
deps = -rrequirements.txt
commands =
pytest -v --verify-base-url --base-url {env:BASE_URL:http://web:1443} --driver Remote --capability browserName firefox --host selenium --html=/coverage/send-test.html --self-contained-html {posargs}
[testenv:flake8]
commands =
flake8 {posargs:.}
[flake8]
exclude = .eggs,.tox,docs,node_modules
[pytest]
sensitive_url = mozilla\.(com|org)

Some files were not shown because too many files have changed in this diff Show More