Merge branch 'staging' into oo2

This commit is contained in:
yflory 2018-12-13 16:24:11 +01:00
commit 760f58b74c
139 changed files with 16415 additions and 9509 deletions

View File

@ -2,6 +2,7 @@ node_modules/
www/bower_components/
www/common/pdfjs/
www/common/tippy/
www/common/highlight/
www/common/jquery-ui/
www/common/onlyoffice/*
@ -18,6 +19,7 @@ www/pad/mediatag-plugin-dialog.js
www/pad/disable-base64.js
www/kanban/jkanban.js
www/kanban/jscolor.js
www/common/media-tag-nacl.min.js

View File

@ -1,3 +1,233 @@
# Numbat release (v2.13.0)
## Goals
This release features long-awaited improvements to our Rich Text Pad.
This work was done over a short period, and we're releasing it now so that users can take advantage of the improvements as soon as possible.
## Update notes
* We've fixed a bug related to chat via an update to our messaging server. To install the update, run `npm update`. This server improvement is backwards compatible, so you can update your clientside or serverside dependencies in either order. Restart your server for the changes to take effect.
* You can run `bower update` in order to take advantage of the latest clientside dependencies. Depending on when you last updated you may benefit from updates to Codemirror or some other clientside libraries.
## Features
* We've refactored a great deal of CryptPad's Remote Procedure Call mechanisms related to chat. This should simplify CryptPad and make potential bugs less likely to occur.
## Bugfixes
* The behaviour of the cursor in our rich text editor has been greatly improved. Your experience when collaboratively editing should be noticeably better.
* Characters inserted into rich text pads were sometimes dropped due to a race condition between CKEditor and ChainPad, but this asynchronous behaviour has been resolved. As such the editor should be much more reliable.
* Deleting chat history from the server now removes it from your chat interface and that of remote messengers, where it previously would require a reload of the interface to see the correct chat history.
* We now correctly set owners of a shared chat channel such that either chat participant in a one-to-one room can delete the history.
* If you request history with a `lastKnownHash` which is not in the history, the server informs you that it is not there via a direct message. Clients fall back to a classic full retreival of the history. Previously this would fail, and print a message to the server's stdout.
* Firefox users may have noticed that when they clicked the dropdown menus for styles in the CKEditor toolbar, their scrollbar would jump to the top of the document. Their scroll position is now preserved in cases where it would previously have been disrupted.
# Manatee release (v2.12.0)
## Goals
For this release we aimed to address usability concerns in our Rich Text Pad, since it's our most widely used application. During this time we also received an unexpected security disclusure which we treated as being top priority.
## Update notes
* This release addresses an XSS vulnerability in our chat interface which was discovered thanks to [cyberpunky](https://twitter.com/cyberpunkych). In older versions of CryptPad, only the /contacts/ app was affected. In newer versions which feature the embedded chat interface in pads, it is possible to leverage this vulnerability against other users in the same pad. Due to our [Sandboxed iframe technique](https://blog.cryptpad.fr/2017/08/30/CryptPad-s-new-Secure-Cross-Domain-Iframe/), this vulnerability does not permit an attacker to compromise concurrent editor's accounts, as their user keys are never accessible within the scope of the domain which was subject to exploitation. However, since the chat functionality is available to viewers as well as editors, it could be leveraged to gain access to the keys which permit modification of the document. Despite this limitation, creative attackers could leverage the front-end code to perform phishing attacks, or other forms of social engineering to trick users into handing over their credentials. We recommend that administrators of affected CryptPad instances upgrade to this version as soon as possible. Once more, we'd like to thank _cyberpunky_ for their effort to discover the issue, and for reporting the issue to us in private so that we could fix it without putting our users at risk.
* On a lighter note, this release features a server-side dependency update which fixes a non-critical bug in our websocket protocol. New users joining a channel which had never been vacated by all its users since its creation would receive the full history instead of only the latest state. To deploy the fix, run `npm update` and restart your server.
## Bugfixes
* As noted above, this release fixes an XSS vulnerability.
* We realized that each shared-folder in your CryptDrive was using a separate websocket connection to the server instead of routing over the existing websocket connection. This has been fixed.
* We've improved our _cursor-recovery script_ in the Rich Text Pad app to make it more resilient. In cases where the text changed in two places within one node of the document, your cursor could be displaced. It should behave more predictably now.
* Another problem in the Rich Text Pad app could lead to conflicts between users when one reverted the change of another. Conflicts should now resolve in a predictable fashion.
* If you were using the Rich Text Pad in its reduced-width mode (available via your /settings/ page), it was possible to scroll down beyond the white, paper-like styles of the document into an un-styled area of the page. This has been addressed.
* We discovered that the export functionality for Rich Text Pads was not working due to a semantic difference in a conditional test in Chrome. Export within Chrome should work once more, however, there are [serious privacy risks within Chrome/Chromium](https://reddit.com/r/ProtonMail/comments/9yl94k/never_connect_to_protonmail_using_chrome/) and we recommend that you consider using a more privacy-friendly browser.
## What's new
* The home page now features a badge advertising the fact that CryptPad is now a winner of the NGI award for _Privacy and Trust-enhanced technologies_. You can follow the link to our blog post which contains more information.
* It is now possible to directly download uploaded files from your CryptDrive without opening a new tab, making your content available more quickly.
# Lemur release (v2.11.0)
## Goals
This release continued the work on better customization features for community instances. We also worked on usability improvements and UI issues.
## Update notes
* This is a simple release. Just download the latest commits and update your cache-busting string.
* Customized instances may require additionnal changes in order to make customization easier to maintain in the future.
* The static pages content (home page, FAQ, contact, privacy, etc.) has been moved from `./customize.dist/pages.js` to a `./customize.dist/pages/` directory, containing one file per page. This new structure allows administrators to override only some pages instead of all the pages at once.
* To override a page, just make a copy of its .js file from `./customize.dist/pages` to a `./customize/pages` and make your changes.
## Features
* We've replaced our Font Awesome application icons with new custom icons. The new icons should be closer to the goals of the apps.
* We've cancelled the Ctrl+S shortcut from the browser for saving the page. In CryptPad, the result of the browser save was not usable and the content of the pads is automatically saved.
* As explained above, we've made it easier to customize some specific static pages instead of overriding all of them.
* Our Markdown renderer should display tables in a nicer and cleaner way (*Code* and *Slide* applications).
* The font size in the code and slide editors can now be changed from the *Settings* page.
* We've added a warning text to the CryptDrive export feature from the last release.
## Bugfixes
* We've found an issue causing some deleted characters to be inserted back in the document. It could happen when a least one member of the session had the tab not focused in their browser.
* We've fixed an issue with our code for detecting small (or zoomed) screens in several part of our UI. This will hide some unnecessary elements of the interface at first load and free space for the actual content of the pad.
* The "present" mode in the Slide application will no longer display the toolbar.
* We've fixed an issue in the *Pad* application where the font could be reset to Arial when making a new paragraph.
* The full CryptDrive export no longer stops when trying to export a very old poll.
# Koala release (v2.10.0)
## Goals
This release continued to improve our _shared folder_ functionality, addressed user concerns about data portability, and implemented various features for customization for different CryptPad instances.
## Update notes
* This release features updates to client-side dependencies. Run `bower update` to update the following:
* netflux-websocket
* chainpad-netflux
* we've added a new field (`fileHost`) in `config.example.js`. It informs clientside code what domain they should use when fetching encrypted blobs.
* Administrators can now do more to customize their CryptPad server, most notably via the ability to override specific translations. For example, the home page now features a short message which, by default, says that the server is a community-hosted instance of the CryptPad open-source project. On CryptPad.fr, we have replaced this text to talk about our organization. You can do the same by modifying files in `cryptpad/customize/translations/`, like so:
```
define(['/common/translations/messages.js'], function (Messages) {
// Replace the existing keys in your copied file here:
Messages.home_host = "CryptPad.fr is the official instance of the open-source CryptPad project. It is administered by XWiki SAS, the employee-owned French company which created and maintains the product.";
return Messages;
});
```
Simply change the text assigned to `home_host` with a blurb about your own organization. We'll update the wiki soon with more info about customization.
### Features
* We've updated our features page to indicate what users get by purchasing a premium account. You can visit our accounts page directly from this list with the click of a button.
* We've updated our home page to explain more about what CryptPad is.
* As mentioned above, we've made all of our translation files overrideable.
* We've made it easier to get your data out of CryptPad, by implementing a complete export of your CryptDrive's content as a zip file. This feature is available on the _settings page_.
* Shared folders now support password protection.
### Bugfixes
* We fixed an issue which affected users of our Kanban application, which caused the color picker to pop up and get in the way at inopportune moments.
* We found that when a CryptPad code editor tab finished loading in the background, when it was focused, the markdown preview pane would be blank. We've added a check to try to re-draw the pane in these circumstances.
* We noticed that anonymous users who used our in-pad chat app could not be distinguished when they both chatted at once. We now add a string at the end of their name which makes it possible to distinguish them.
* We've updated an internal library (cryptget) such that it correctly tears down realtime sessions after connecting and loading content from the server.
* We also added better error handling.
* At some point in the last few releases we broke export of media-tags in rich text pads. They should be back to normal now.
* Media-Tags also use the configurable value `fileHost` to construct absolute URLs, instead of using relative URLs to the server.
* Tall dropdown menus no longer use scrollbars when they are displayed with enough space to display all options.
* Chrome browser seemed to display our rich text editor correctly, except that no cursor was visible in empty documents. Users will now be able to see where their cursor is placed.
* It was possible for disconnected users' browsers to enter a bad state after reconnecting. This resulted in that pad being inaccessible until they relaunched their browser. This bad state is now detected and mitigated.
* Tags for documents in the CryptDrive were stopped functioning correctly as of the last few releases. This release fixes this bug.
# Jerboa release (v2.9.0)
## Goals
Since last release introduced several big features, this release was allocated towards usability improvements largely related to those new features.
## Update notes
This is a simple release. Just deploy the latest source.
### Features
* At a user's request, we now highlight annotated code blocks according to their language's syntax
* Shared folders can now be viewed by unregistered users (in read-only mode)
* The authentication process that we use for handling accounts has been improved so as to tolerate very slow networks more effectively
* The chat system embedded within pads can now optionally use the browser's system notifications API
### Bugfixes
* We found and fixed a race condition when initializing two tabs at once, which could leave one of the tabs in a broken state
# Ibis release (v2.8.0)
## Goals
We've been making use of some hidden features for a while, to make sure that they were safe to deploy.
This release, we worked on making _contextual chat_ and _shared folders_ available to everyone.
## Update notes
* run `bower update` to download an updated version of _marked.js_
### Features
* Our kanban application now features a much more consistent and flexible colorpicker, thanks to @MTRNord (https://github.com/MTRNord)
* File upload dialogs now allow you to upload multiple files at once
* Updated German translations thanks to [b3yond](https://github.com/b3yond/)
* An explicit pad storage policy to better suit different privacy constraints
* _import local pads_ at login time is no longer default
* An embedded chat room in every pad, so you can work alongside your fellow editors more easily
* Promotion of our [crowdfunding campaign](https://opencollective.com/cryptpad), including a button on the home page, and a one-time dialog for users
### Bug fixes
* Updating our markdown library resolved an issue which incorrectly rendered links containing parentheses.
* We discovered an issue logging in with _very old_ credentials which were initialized without a public key. We now regenerate your keyring if you do not have public keys stored in association with your account.
* We found another bug in our login process; under certain conditions the terminating function could be called more than once.
# Hedgehog release (v2.7.0)
## Goals
This release overlapped with the publication and presentation of a paper written about CryptPad's architecture.
As such, we didn't plan for any very ambitious new features, and instead focused on bug fixes and some new workflows.
## Update notes
This is a fairly simple release. Just download the latest commits and update your cache-busting string.
### Features
* In order to address some privacy concerns, we've changed CryptPad such that pads are not immediately stored in your CryptDrive as soon as you open them. Instead, users are presented with a prompt in the bottom-right corner which asks them whether they'd like to store it manually. Alternatively, you can use your settings page to revert to the old automatic behaviour, or choose not to store, and to never be asked.
* It was brought to our attention that it was possible to upload base64-encoded images in the rich text editor. These images had a negative performance impact on such pads. From now on, if these images are detected in a pad, users are prompted to run a migration to convert them to uploaded (and encrypted) files.
* We've added a progress bar which is displayed while you are loading a pad, as we found that it was not very clear whether large pads were loading, or if they had become unresponsive due to a bug.
* We've added an option to allow users to right-click uploaded files wherever they appear, and to store that file in their CryptDrive.
* We've improved the dialog which is used to modify the properties of encrypted media embedded within rich text pads.
### Bug fixes
* Due to a particularly disastrous bug in Chrome 68 which was unfortunately beyond our power to fix, we've added a warning for anyone affected by that bug to let them know the cause.
* We've increased the module loading timeout value used by requirejs in our sharedWorker implementation to match the value used by the rest of CryptPad.
# Gibbon release (v2.6.0)
## Goals
For this release we focused on deploying two very large changes in CryptPad.
For one, we'd worked on a large refactoring of the system we use to compile CSS from LESS, so as to make it more efficient.
Secondly, we reworked the architecture we use for implementing the CryptDrive functionality, so as to integrate support for shared folders.
## Update notes
To test the _shared folders_ functionality, users can run the following command in their browser console:
`localStorage.CryptPad_SF = "1";`
Alternatively, if the instance administrator would like to enable shared folders for all users, they can do so via their `/customize/application_config.js` file, by adding the following line:
`config.disableSharedFolders = true;`
### Features
* As mentioned in the _goals_ for this release, we've merged in the work done to drastically improve performance when compiling styles. The system features documentation for anyone interested in understanding how it works.
* We've refactored the APIs used to interact with your CryptDrive, implementing a single interface with which applications can interact, which then manages any number of sub-objects each representing a shared folder. Shared folders are still disabled by default. See the _Update notes_ section for more information.
* The home page now features the same footer which has been displayed on all other information pages until now.
* We've added a slightly nicer spinner icon on loading pages.
* We've created a custom font _cp-tools_ for our custom-designed icons
### Bug fixes
* We've accepted a pull request implementing serverside support for moving files across different drives, for system administrators hosting CryptPad on systems which segregate folders on different partitions.
* We've addressed a report of an edge case in CryptPad's user password change logic which could cause users to delete their accounts.
# Fossa release (v2.5.0)
## Goals

View File

@ -24,7 +24,7 @@
"ckeditor": "4.7.3",
"codemirror": "^5.19.0",
"requirejs": "2.3.5",
"marked": "0.3.5",
"marked": "0.5.0",
"rangy": "rangy-release#~1.3.0",
"json.sortify": "~2.1.0",
"secure-fabric.js": "secure-v1.7.9",
@ -46,7 +46,8 @@
"html2canvas": "^0.4.1",
"croppie": "^2.5.0",
"sortablejs": "#^1.6.0",
"saferphore": "^0.0.1"
"saferphore": "^0.0.1",
"jszip": "Stuk/jszip#^3.1.5"
},
"resolutions": {
"bootstrap": "^v4.0.0"

View File

@ -2,7 +2,7 @@
/*
globals module
*/
var domain = 'http://localhost:3000/';
var _domain = 'http://localhost:3000/';
// You can `kill -USR2` the node process and it will write out a heap dump.
// If your system doesn't support dumping, comment this out and install with
@ -15,7 +15,7 @@ var domain = 'http://localhost:3000/';
// we prepend a space because every usage expects it
// requiring admins to preserve it is unnecessarily confusing
domain = ' ' + domain;
var domain = ' ' + _domain;
module.exports = {
// the address you want to bind to, :: means all ipv4 and ipv6 addresses
@ -137,34 +137,27 @@ module.exports = {
/* Limits, Donations, Subscriptions and Contact
*
* By default, CryptPad limits every registered user to 50MB of storage. It also shows a
* donate button which allows for making a donation to support CryptPad development.
* subscribe button which allows them to upgrade to a paid account. We handle payment,
* and keep 50% of the proceeds to fund ongoing development.
*
* You can:
* A: leave things as they are
* B: disable accounts but display a donate button
* C: hide any reference to paid accounts or donation
*
* If you chose A then there's nothing to do.
* If you chose B, set 'allowSubscriptions' to false.
* If you chose C, set 'removeDonateButton' to true
*/
allowSubscriptions: true,
removeDonateButton: false,
/* Sales coming from your server will be identified by your domain
*
* You can either:
* A: Leave it exactly as it is.
* B: Hide the donate button.
* C: Change the donate button to a subscribe button, people who subscribe will get more
* storage on your instance and you get 50% of the revenue earned.
*
* CryptPad is developed by people who need to live and who deserve an equivilent life to
* what they would get at a company which monitizes user data. However, we intend to have
* a mutually positive relationship with every one of our users, including you. If you are
* getting value from CryptPad, you should be giving equal value back.
*
* If you are using CryptPad in a business context, please consider taking a support contract
* by contacting sales@cryptpad.fr
*
* If you choose A then there's nothing to do.
*
* If you choose B, set this variable to true and it will remove the donate button.
*/
removeDonateButton: false,
/*
* If you choose C, set allowSubscriptions to true, then set myDomain to the domain which people
* use to reach your CryptPad instance. Then contact sales@cryptpad.fr and tell us your domain.
* We will tell you what is needed to get paid.
*/
allowSubscriptions: false,
myDomain: 'i.did.not.read.my.config.myserver.tld',
myDomain: _domain,
/*
* If you are using CryptPad internally and you want to increase the per-user storage limit,

View File

@ -1,135 +1,205 @@
/*
Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/
body
{
/* Font */
font-family: sans-serif, Arial, Verdana, "Trebuchet MS";
font-size: 13px;
/* Text color */
color: #333;
/* Remove the background color to make it transparent */
background-color: #fff;
margin: 20px;
}
.cke_editable
{
font-size: 16px;
line-height: 1.6;
/* Fix for missing scrollbars with RTL texts. (#10488) */
word-wrap: break-word;
}
blockquote
{
font-style: italic;
font-family: Georgia, Times, "Times New Roman", serif;
padding: 2px 0;
border-style: solid;
border-color: #ccc;
border-width: 0;
}
.cke_contents_ltr blockquote
{
padding-left: 20px;
padding-right: 8px;
border-left-width: 5px;
}
.cke_contents_rtl blockquote
{
padding-left: 8px;
padding-right: 20px;
border-right-width: 5px;
}
a
{
color: #0782C1;
}
ol,ul,dl
{
/* IE7: reset rtl list margin. (#7334) */
*margin-right: 0px;
/* preserved spaces for list items with text direction other than the list. (#6249,#8049)*/
padding: 0 40px;
}
h1,h2,h3,h4,h5,h6
{
font-weight: normal;
line-height: 1.2;
}
hr
{
border: 0px;
border-top: 1px solid #ccc;
}
img.right
{
border: 1px solid #ccc;
float: right;
margin-left: 15px;
padding: 5px;
}
img.left
{
border: 1px solid #ccc;
float: left;
margin-right: 15px;
padding: 5px;
}
pre
{
white-space: pre-wrap; /* CSS 2.1 */
word-wrap: break-word; /* IE7 */
-moz-tab-size: 4;
tab-size: 4;
}
.marker
{
background-color: Yellow;
}
span[lang]
{
font-style: italic;
}
figure
{
text-align: center;
border: solid 1px #ccc;
border-radius: 2px;
background: rgba(0,0,0,0.05);
padding: 10px;
margin: 10px 20px;
display: inline-block;
}
figure > figcaption
{
text-align: center;
display: block; /* For IE8 */
}
a > img {
padding: 1px;
margin: 1px;
border: none;
outline: 1px solid #0782C1;
}
/*
Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/
body
{
/* Font */
font-family: sans-serif, Arial, Verdana, "Trebuchet MS";
font-size: 13px;
/* Text color */
color: #333;
/* Remove the background color to make it transparent */
background-color: #fff;
margin: 0;
padding: 20px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
/* Remove margin-top for the first element */
body > *:first-child {
margin-top: 0;
}
/* If the magic line is the first element, remove margin-top for the next one */
body > .non-realtime:first-child + * {
margin-top: 0;
}
.cke_editable
{
font-size: 16px;
line-height: 1.6;
/* Fix for missing scrollbars with RTL texts. (#10488) */
word-wrap: break-word;
}
blockquote
{
font-style: italic;
font-family: Georgia, Times, "Times New Roman", serif;
padding: 2px 0;
border-style: solid;
border-color: #ccc;
border-width: 0;
}
.cke_contents_ltr blockquote
{
padding-left: 20px;
padding-right: 8px;
border-left-width: 5px;
}
.cke_contents_rtl blockquote
{
padding-left: 8px;
padding-right: 20px;
border-right-width: 5px;
}
a
{
color: #0782C1;
}
ol,ul,dl
{
/* IE7: reset rtl list margin. (#7334) */
*margin-right: 0px;
/* preserved spaces for list items with text direction other than the list. (#6249,#8049)*/
padding: 0 40px;
}
h1,h2,h3,h4,h5,h6
{
font-weight: normal;
line-height: 1.2;
}
hr
{
border: 0px;
border-top: 1px solid #ccc;
}
img.right
{
border: 1px solid #ccc;
float: right;
margin-left: 15px;
padding: 5px;
}
img.left
{
border: 1px solid #ccc;
float: left;
margin-right: 15px;
padding: 5px;
}
pre
{
white-space: pre-wrap; /* CSS 2.1 */
word-wrap: break-word; /* IE7 */
-moz-tab-size: 4;
tab-size: 4;
}
.marker
{
background-color: Yellow;
}
span[lang]
{
font-style: italic;
}
figure
{
text-align: center;
border: solid 1px #ccc;
border-radius: 2px;
background: rgba(0,0,0,0.05);
padding: 10px;
margin: 10px 20px;
display: inline-block;
}
figure > figcaption
{
text-align: center;
display: block; /* For IE8 */
}
a > img {
padding: 1px;
margin: 1px;
border: none;
outline: 1px solid #0782C1;
}
.cp-cursor-position {
cursor: default;
background-color: red;
background-clip: padding-box;
padding: 0 1px;
border: 2px solid red;
border-right-color: transparent !important;
border-left-color: transparent !important;
margin-left: -2px;
margin-right: -2px;
}
.cp-cursor-position[data-type="start"] {
border-left: none;
border-right-width: 4px;
margin-right: -4px;
}
.cp-cursor-position[data-type="end"] {
border-right: none;
border-left-width: 4px;
margin-left: -4px;
}
.cp-cursor-avatar {
display: flex;
align-items: center;
}
.cp-cursor-avatar media-tag {
min-height: 32px;
max-height: 32px;
min-width: 32px;
max-width: 32px;
margin-right: 10px;
}
.cp-cursor-avatar media-tag img {
border-radius: 4px;
max-height: 100%;
max-width: 100%;
}
.cp-link-clicked {
position: absolute;
background: white;
border: 1px solid #333;
border-radius: 5px;
padding: 3px 8px;
display: inline-block;
max-width: 200px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.cp-link-clicked a {
cursor: pointer;
}

View File

@ -7,6 +7,20 @@
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe900;" glyph-name="template" horiz-adv-x="876" d="M804.244 960h-732.699c-39.513 0-71.545-32.032-71.545-71.545v0-880.909c0-39.513 32.032-71.545 71.545-71.545v0h732.699c39.513 0 71.545 32.032 71.545 71.545v0 880.909c0 39.513-32.032 71.545-71.545 71.545v0zM808.421 7.545c0-2.307-1.87-4.177-4.177-4.177v0h-732.699c-2.307 0-4.177 1.87-4.177 4.177v0 880.909c0 2.307 1.87 4.177 4.177 4.177v0h732.699c2.307 0 4.177-1.87 4.177-4.177v0zM107.789 852.211h660.211v-256h-660.211v256zM107.789 555.789h269.474v-256h-269.474v256zM417.684 70.737h350.316v-26.947h-350.316v26.947zM417.684 133.659h350.316v-26.947h-350.316v26.947zM417.684 196.446h350.316v-26.947h-350.316v26.947zM417.684 259.368h350.316v-26.947h-350.316v26.947zM417.684 555.789h350.316v-26.947h-350.316v26.947zM417.684 498.526h350.316v-26.947h-350.316v26.947zM417.684 441.263h350.316v-26.947h-350.316v26.947zM417.684 384h350.316v-26.947h-350.316v26.947zM417.684 326.737h350.316v-26.947h-350.316v26.947zM107.789 259.368h269.474v-215.579h-269.474v215.579z" />
<glyph unicode="&#xe901;" glyph-name="new-template" horiz-adv-x="920" d="M103.696 856.304h635.139v-246.278h-635.139v246.278zM103.696 571.139h259.241v-246.278h-259.241v246.278zM401.823 165.039h337.013v-25.924h-337.013v25.924zM401.823 225.442h337.013v-25.924h-337.013v25.924zM401.823 285.975h337.013v-25.924h-337.013v25.924zM401.823 571.139h337.013v-25.924h-337.013v25.924zM401.823 516.051h337.013v-25.924h-337.013v25.924zM401.823 460.962h337.013v-25.924h-337.013v25.924zM401.823 405.873h337.013v-25.924h-337.013v25.924zM401.823 350.785h337.013v-25.924h-337.013v25.924zM103.696 285.975h259.241v-207.392h-259.241v207.392zM842.532 140.152v751.020c0 38.013-30.816 68.828-68.828 68.828v0h-704.875c-38.013 0-68.828-30.816-68.828-68.828v0-847.457c0-38.013 30.816-68.828 68.828-68.828v0h666.896c19.163-23.765 48.277-38.841 80.912-38.841 57.27 0 103.696 46.426 103.696 103.696 0 48.068-32.706 88.497-77.078 100.248l-0.724 0.163zM68.828 39.696c-2.219 0-4.018 1.799-4.018 4.018v0 847.457c0 2.219 1.799 4.018 4.018 4.018v0h704.875c2.219 0 4.018-1.799 4.018-4.018v0-755.297c-16.886-6.977-31.013-17.69-41.84-31.166l-0.157-0.202h-333.902v-25.924h318.607c-4.743-11.511-7.504-24.874-7.518-38.881v-0.006zM816.608-51.038c-50.111 0-90.734 40.623-90.734 90.734v0c0 0.068 0 0.148 0 0.228 0 14.058 3.253 27.357 9.047 39.184l-0.233-0.526c1.324 3.018 2.711 5.571 4.28 7.995l-0.132-0.218c9.3 15.303 22.547 27.384 38.344 35.021l0.542 0.236c11.301 5.562 24.6 8.814 38.658 8.814 0.080 0 0.16 0 0.241 0h-0.012c50.111 0 90.734-40.623 90.734-90.734s-40.623-90.734-90.734-90.734v0zM861.975 52.658h-32.405v32.405c0 3.579-2.902 6.481-6.481 6.481v0h-12.962c-3.579 0-6.481-2.902-6.481-6.481v0-32.405h-32.405c-3.579 0-6.481-2.902-6.481-6.481v0-12.962c0-3.579 2.902-6.481 6.481-6.481v0h32.405v-32.405c0-3.579 2.902-6.481 6.481-6.481v0h12.962c3.579 0 6.481 2.902 6.481 6.481v0 32.405h32.405c3.579 0 6.481 2.902 6.481 6.481v0 12.962c0 3.579-2.902 6.481-6.481 6.481v0z" />
<glyph unicode="&#xe900;" glyph-name="template" d="M839.56 905.788h-655.119c-35.33 0-63.97-28.64-63.97-63.97v-787.637c0-35.33 28.64-63.97 63.97-63.97v0h655.119c35.33 0 63.97 28.64 63.97 63.97v0 787.637c0 35.33-28.64 63.97-63.97 63.97v0zM843.294 54.182c0-2.063-1.672-3.735-3.735-3.735v0h-655.119c-2.063 0-3.735 1.672-3.735 3.735v0 787.637c0 2.063 1.672 3.735 3.735 3.735v0h655.119c2.063 0 3.735-1.672 3.735-3.735v0 0zM216.847 809.412h590.306v-228.894h-590.306v228.894zM216.847 544.376h240.941v-228.894h-240.941v228.894zM493.929 110.682h313.224v-24.094h-313.224v24.094zM493.929 166.942h313.224v-24.094h-313.224v24.094zM493.929 223.081h313.224v-24.094h-313.224v24.094zM493.929 279.341h313.224v-24.094h-313.224v24.094zM493.929 544.376h313.224v-24.094h-313.224v24.094zM493.929 493.176h313.224v-24.094h-313.224v24.094zM493.929 441.976h313.224v-24.094h-313.224v24.094zM493.929 390.776h313.224v-24.094h-313.224v24.094zM493.929 339.576h313.224v-24.094h-313.224v24.094zM216.847 279.341h240.941v-192.753h-240.941v192.753z" />
<glyph unicode="&#xe901;" glyph-name="new-template" d="M840.764 886.152h-655.119c-35.33 0-63.97-28.64-63.97-63.97v0-787.637c0-35.33 28.64-63.97 63.97-63.97v0h655.119c35.33 0 63.97 28.64 63.97 63.97v0 787.637c0 35.33-28.64 63.97-63.97 63.97v0zM844.499 34.545c0-2.063-1.672-3.735-3.735-3.735v0h-655.119c-2.063 0-3.735 1.672-3.735 3.735v0 787.637c0 2.063 1.672 3.735 3.735 3.735h655.119c2.063 0 3.735-1.672 3.735-3.735v0zM643.915 466.071h-93.365v93.003c0 10.313-8.36 18.673-18.673 18.673v0h-37.346c-0.036 0-0.078 0-0.121 0-10.246 0-18.552-8.306-18.552-18.552 0-0.042 0-0.085 0-0.127v0.006-93.003h-93.365c-0.036 0-0.078 0-0.121 0-10.246 0-18.552-8.306-18.552-18.552 0-0.042 0-0.085 0-0.127v0.006-37.346c0-10.313 8.36-18.673 18.673-18.673v0h93.365v-93.967c0-0.036 0-0.078 0-0.121 0-10.246 8.306-18.552 18.552-18.552 0.042 0 0.085 0 0.127 0h37.34c10.313 0 18.673 8.36 18.673 18.673v0 93.606h93.365c10.285 0.068 18.605 8.388 18.673 18.666v37.352c0.002 0.108 0.003 0.234 0.003 0.361 0 10.313-8.36 18.673-18.673 18.673-0.001 0-0.002 0-0.004 0v0z" />
<glyph unicode="&#xe902;" glyph-name="slide" d="M939.671 758.453h-397.553v29.636c0 16.833-13.646 30.479-30.479 30.479s-30.479-13.646-30.479-30.479v0-29.636h-396.83c-16.053-1.040-28.68-14.315-28.68-30.539s12.627-29.5 28.59-30.535l0.091-0.005h30.961v-448.151c0-0.036 0-0.079 0-0.121 0-22.87 18.471-41.425 41.309-41.562h292.516l-78.185-78.065c-5.102-5.453-8.235-12.803-8.235-20.884 0-16.9 13.7-30.6 30.6-30.6 8.082 0 15.432 3.133 20.902 8.251l-0.017-0.016 107.46 107.58 107.58-107.58c5.523-5.509 13.146-8.915 21.564-8.915 16.866 0 30.539 13.673 30.539 30.539 0 8.448-3.43 16.095-8.974 21.624l-78.066 78.066h273.107c22.85 0.137 41.322 18.692 41.322 41.562 0 0.043 0 0.085 0 0.128v-0.007 448.151h30.961c16.053 1.040 28.68 14.315 28.68 30.539s-12.627 29.5-28.59 30.535l-0.091 0.005zM848.113 268.619h-671.864v428.755h671.503zM493.688 419.569h317.44v-24.456h-317.44v24.456zM493.688 476.552h317.44v-24.456h-317.44v24.456zM493.688 533.414h317.44v-24.456h-317.44v24.456zM493.688 590.396h317.44v-24.456h-317.44v24.456zM212.872 590.396h244.194v-195.283h-244.194v195.283z" />
<glyph unicode="&#xe903;" glyph-name="shared-folder" d="M829.44 727.251h-296.84l-47.104 62.886c-25.923 34.066-66.406 55.898-111.999 56.139h-178.938c-77.457-0.137-140.211-62.891-140.348-140.335v-515.868c0.137-77.457 62.891-140.211 140.335-140.348h634.893c77.457 0.137 140.211 62.891 140.348 140.335v396.482c0 0.036 0 0.078 0 0.121 0 77.561-62.807 140.452-140.335 140.589h-0.013zM911.119 190.072c-0.068-45.083-36.597-81.611-81.673-81.679h-634.887c-45.083 0.068-81.611 36.597-81.679 81.673v515.862c0.068 45.083 36.597 81.611 81.673 81.679h178.906c26.48-0.030 50.004-12.656 64.908-32.207l0.146-0.199 47.104-62.765 17.709-24.094h326.114c45.125-0.069 81.679-36.665 81.679-81.799 0 0 0 0 0 0v0zM614.4 451.132c0.071 0 0.156 0 0.24 0 34.132 0 61.801 27.669 61.801 61.801s-27.669 61.801-61.801 61.801c-34.047 0-61.664-27.532-61.801-61.547v-0.013c0-0.018 0-0.040 0-0.061 0-7.309 1.235-14.33 3.508-20.865l-0.135 0.446-103.966-60.235c-0.474 0.655-1.031 1.213-1.665 1.672l-0.021 0.015c-10.785 9.46-25.010 15.231-40.582 15.231-34.065 0-61.681-27.615-61.681-61.681 0-11.035 2.898-21.393 7.974-30.355l-0.16 0.307c11.046-18 30.619-29.824 52.953-29.824 16.92 0 32.255 6.786 43.431 17.785l-0.008-0.008 103.966-60.235c-2.138-5.921-3.374-12.754-3.374-19.876 0-0.085 0-0.171 0.001-0.256v0.013c-0.003-0.217-0.005-0.474-0.005-0.731 0-7.409 1.417-14.486 3.994-20.977l-0.135 0.384c8.944-23.66 31.407-40.178 57.728-40.178 33.999 0 61.56 27.562 61.56 61.56 0 28.833-19.822 53.036-46.582 59.725l-0.424 0.090c-4.366 1.539-9.418 2.572-14.664 2.884l-0.154 0.007c-19.639 0-37.082-9.398-48.078-23.943l-0.11-0.152-101.798 59.031c3.729 7.764 5.908 16.879 5.908 26.504s-2.179 18.74-6.070 26.88l0.162-0.376 101.798 58.79c11.336-14.332 28.681-23.481 48.167-23.612h0.022z" />
<glyph unicode="&#xe904;" glyph-name="poll" d="M859.076 905.788h-655.119c-35.33 0-63.97-28.64-63.97-63.97v0-787.637c0-35.33 28.64-63.97 63.97-63.97v0h655.119c35.33 0 63.97 28.64 63.97 63.97v0 787.637c0 35.33-28.64 63.97-63.97 63.97v0zM862.81 54.182c0-2.063-1.672-3.735-3.735-3.735v0h-655.119c-2.063 0-3.735 1.672-3.735 3.735v0 787.637c0 2.063 1.672 3.735 3.735 3.735v0h655.119c2.063 0 3.735-1.672 3.735-3.735v0zM329.487 543.895h48.188v-346.714h-48.188v346.714zM507.422 698.82h48.188v-501.76h-48.188v501.76zM685.237 449.687h48.188v-252.506h-48.188v252.506z" />
<glyph unicode="&#xe905;" glyph-name="file-upload" d="M843.294 54.182c0-2.063-1.672-3.735-3.735-3.735v0h-655.119c-2.063 0-3.735 1.672-3.735 3.735v0 787.637c0 2.063 1.672 3.735 3.735 3.735v0h454.054v60.235h-454.054c-35.33 0-63.97-28.64-63.97-63.97v-787.637c0-35.33 28.64-63.97 63.97-63.97v0h655.119c35.33 0 63.97 28.64 63.97 63.97v0 540.19h-60.235zM843.294 696.772l-174.2 209.016v-281.299h234.436l-60.235 72.282zM461.161 238.984h102.039v203.957h72.523l-123.723 214.076-123.723-214.076h72.885v-203.957z" />
<glyph unicode="&#xe906;" glyph-name="whiteboard" d="M904.132 845.553h-783.661c-0.18 0.002-0.392 0.003-0.605 0.003-36.261 0-65.656-29.395-65.656-65.656 0-0.213 0.001-0.425 0.003-0.638v0.032-663.793c0.339-36.002 29.603-65.057 65.654-65.057 0.213 0 0.425 0.001 0.637 0.003h784.232c36.261 0 65.656 29.395 65.656 65.656v663.191c0.002 0.18 0.003 0.392 0.003 0.605 0 36.261-29.395 65.656-65.656 65.656-0.213 0-0.425-0.001-0.638-0.003h0.032zM909.553 116.104c0-2.994-2.427-5.421-5.421-5.421v0h-783.661c-2.994 0-5.421 2.427-5.421 5.421v663.191c-0.021 0.181-0.034 0.39-0.034 0.602 0 2.994 2.427 5.421 5.421 5.421 0.012 0 0.024 0 0.035 0h784.262c2.994 0 5.421-2.427 5.421-5.421v0zM612.593 219.588h235.761v-48.188h-235.761v48.188z" />
<glyph unicode="&#xe907;" glyph-name="todo" d="M839.56 905.788h-655.119c-35.33 0-63.97-28.64-63.97-63.97v-787.637c0-35.33 28.64-63.97 63.97-63.97v0h655.119c35.33 0 63.97 28.64 63.97 63.97v0 787.637c0 35.33-28.64 63.97-63.97 63.97v0zM843.294 54.182c0-2.063-1.672-3.735-3.735-3.735v0h-655.119c-2.063 0-3.735 1.672-3.735 3.735v0 787.637c0 2.063 1.672 3.735 3.735 3.735v0h655.119c2.063 0 3.735-1.672 3.735-3.735v0zM325.512 404.992h481.28v-48.188h-481.28v48.188zM217.208 417.039h72.282v-72.282h-72.282v72.282zM325.512 270.908h481.28v-48.188h-481.28v48.188zM217.208 282.955h72.282v-72.282h-72.282v72.282zM325.512 673.28h481.28v-48.188h-481.28v48.188zM216.847 613.045h72.282v72.282h-72.282zM230.701 648.463c0.353 0.416 0.864 0.688 1.44 0.723h0.006c0.623-0.015 1.178-0.29 1.564-0.721l10.965-10.965 27.708 27.708c0.215 0.083 0.463 0.132 0.723 0.132s0.508-0.048 0.737-0.137l-0.014 0.005c1.131 0 2.048-0.917 2.048-2.048v0c-0.018-0.601-0.243-1.146-0.605-1.57l0.003 0.003-29.154-29.033c-0.090-0.024-0.194-0.038-0.301-0.038s-0.211 0.014-0.31 0.040l0.008-0.002h-1.687c-0.090-0.024-0.194-0.038-0.301-0.038s-0.211 0.014-0.31 0.040l0.008-0.002-12.047 12.047c-0.336 0.39-0.556 0.888-0.602 1.437l-0.001 0.009c-0.126 0.258-0.2 0.562-0.2 0.883 0 0.605 0.263 1.149 0.68 1.524l0.002 0.002zM325.512 539.196h481.28v-48.188h-481.28v48.188zM216.847 478.961h72.282v72.282h-72.282zM231.063 514.259c0.352 0.372 0.849 0.603 1.4 0.603 0.016 0 0.032 0 0.048-0.001h-0.002c0.034 0.002 0.073 0.003 0.112 0.003 0.568 0 1.083-0.231 1.454-0.605v0l10.963-10.963 27.708 27.708c0.37 0.371 0.881 0.601 1.445 0.602v0c0.557-0.046 1.056-0.266 1.449-0.605l-0.003 0.003c0.36-0.42 0.584-0.965 0.602-1.562v-0.004c-0.046-0.557-0.266-1.056-0.605-1.449l0.003 0.003-29.154-29.033c-0.089-0.035-0.193-0.056-0.301-0.056s-0.212 0.020-0.307 0.058l0.006-0.002h-1.687c-0.089-0.035-0.193-0.056-0.301-0.056s-0.212 0.020-0.307 0.058l0.006-0.002-12.047 12.047c-0.369 0.37-0.597 0.881-0.597 1.446s0.228 1.075 0.597 1.446v0z" />
<glyph unicode="&#xe908;" glyph-name="pad" d="M839.56 905.788h-655.119c-35.33 0-63.97-28.64-63.97-63.97v-787.637c0-35.33 28.64-63.97 63.97-63.97v0h655.119c35.33 0 63.97 28.64 63.97 63.97v0 787.637c0 35.33-28.64 63.97-63.97 63.97v0zM843.294 54.182c0-2.063-1.672-3.735-3.735-3.735v0h-655.119c-2.063 0-3.735 1.672-3.735 3.735v0 787.637c0 2.063 1.672 3.735 3.735 3.735v0h655.119c2.063 0 3.735-1.672 3.735-3.735v0 0zM216.847 809.412h590.306v-23.974h-590.306v23.974zM216.847 761.224h590.306v-23.974h-590.306v23.974zM216.847 713.035h590.306v-23.974h-590.306v23.974zM216.847 664.847h590.306v-144.444h-590.306v144.444zM493.929 110.682h313.224v-24.094h-313.224v24.094zM493.929 166.942h313.224v-24.094h-313.224v24.094zM493.929 223.081h313.224v-24.094h-313.224v24.094zM493.929 279.341h313.224v-24.094h-313.224v24.094zM216.847 493.176h590.306v-24.094h-590.306v24.094zM216.847 441.976h590.306v-24.094h-590.306v24.094zM216.847 390.776h590.306v-24.094h-590.306v24.094zM216.847 339.576h590.306v-24.094h-590.306v24.094zM216.847 279.341h240.941v-192.753h-240.941v192.753z" />
<glyph unicode="&#xe909;" glyph-name="folder-open" d="M100.232 590.035h828.717c-5.175 69.899-63.091 124.668-133.829 124.808h-283.843l-44.936 60.235c-24.766 32.712-63.599 53.649-107.326 53.73h-170.599c-0.036 0-0.078 0-0.121 0-73.968 0-133.946-59.894-134.084-133.83v-213.366l10.12 76.74c2.295 17.95 17.476 31.684 35.865 31.684 0.012 0 0.025 0 0.037 0h-0.002zM929.19 541.606h-805.948c-13.269-0.004-24.238-9.848-26.006-22.632l-0.016-0.137-43.008-317.801c-0.002-0.261-0.003-0.569-0.003-0.877 0-6.111 0.483-12.11 1.413-17.96l-0.085 0.646c0.904-6.888 2.169-12.966 3.837-18.875l-0.223 0.925c16.563-56.812 68.138-97.63 129.257-97.702h606.698c61.093 0.086 112.628 40.906 128.907 96.752l0.237 0.95c1.459 5.065 2.725 11.228 3.544 17.531l0.070 0.66c0.844 5.201 1.327 11.196 1.327 17.304 0 0.227-0.001 0.454-0.002 0.681v-0.035l40.237 295.755c0.219 1.556 0.344 3.354 0.344 5.18 0 21.624-17.529 39.153-39.153 39.153-0.036 0-0.073 0-0.109 0h0.006z" />
<glyph unicode="&#xe90a;" glyph-name="kanban" d="M839.56 905.788h-655.119c-35.33 0-63.97-28.64-63.97-63.97v-787.637c0-35.33 28.64-63.97 63.97-63.97v0h655.119c35.33 0 63.97 28.64 63.97 63.97v0 787.637c0 35.33-28.64 63.97-63.97 63.97v0zM843.294 54.182c0-2.063-1.672-3.735-3.735-3.735v0h-655.119c-2.063 0-3.735 1.672-3.735 3.735v0 787.637c0 2.063 1.672 3.735 3.735 3.735v0h655.119c2.063 0 3.735-1.672 3.735-3.735v0zM217.329 809.894h144.565v-96.376h-144.565v96.376zM438.754 809.894h144.565v-96.376h-144.565v96.376zM660.299 809.894h144.565v-96.376h-144.565v96.376zM217.329 665.329h144.565v-96.376h-144.565v96.376zM438.754 665.329h144.565v-96.376h-144.565v96.376zM660.299 665.329h144.565v-96.376h-144.565v96.376zM217.329 520.764h144.565v-96.376h-144.565v96.376zM438.754 520.764h144.565v-96.376h-144.565v96.376zM660.299 520.764h144.565v-96.376h-144.565v96.376zM217.329 376.2h144.565v-96.376h-144.565v96.376zM660.299 376.2h144.565v-96.376h-144.565v96.376zM217.329 231.635h144.565v-96.376h-144.565v96.376z" />
<glyph unicode="&#xe90b;" glyph-name="folder" d="M373.459 846.276h-178.899c-77.457-0.137-140.211-62.891-140.348-140.335v-515.868c0.137-77.457 62.891-140.211 140.335-140.348h634.893c77.457 0.137 140.211 62.891 140.348 140.335v396.482c0 0.036 0 0.078 0 0.121 0 77.561-62.807 140.452-140.335 140.589h-296.853l-47.104 62.886c-25.923 34.066-66.406 55.898-111.999 56.139h-0.039z" />
<glyph unicode="&#xe90c;" glyph-name="shared-folder-open" d="M98.424 593.288h797.274c-4.8 67.457-60.657 120.376-128.894 120.471h-272.876l-43.249 57.705c-23.816 31.47-61.17 51.611-103.232 51.682h-164.213c-0.036 0-0.079 0-0.121 0-71.191 0-128.904-57.712-128.904-128.904 0-0.17 0-0.339 0.001-0.508v0.026-204.8l9.638 73.487c2.062 17.437 16.753 30.833 34.574 30.84h0.001zM900.759 255.608l33.973 248.049c0.196 1.447 0.308 3.12 0.308 4.819 0 20.873-16.906 37.797-37.772 37.828h-776.797c-12.746-0.016-23.272-9.5-24.923-21.796l-0.014-0.129-41.321-304.791c-0.002-0.25-0.003-0.546-0.003-0.843 0-5.87 0.483-11.628 1.412-17.235l-0.083 0.609c0.793-6.689 1.977-12.655 3.576-18.449l-0.203 0.861c15.92-54.648 65.53-93.912 124.319-93.967h583.566c0.061 0 0.133 0 0.205 0 16.48 0 32.227 3.14 46.675 8.853l-0.86-0.3c16.639-15.985 39.283-25.829 64.225-25.829 51.231 0 92.762 41.531 92.762 92.762 0 42.798-28.984 78.827-68.394 89.528l-0.65 0.15zM766.795 148.51h-583.56c-32.265 0.073-59.5 21.523-68.297 50.935l-0.13 0.506c-0.742 2.66-1.376 5.889-1.775 9.19l-0.032 0.327v1.566c0 1.566 0 3.373 0 5.301l36.382 272.023h724.751l-32.407-236.845c-1.82-0.63-3.331-1.281-4.788-2.025l0.21 0.097c-16.682-8.067-30.192-20.454-39.403-35.727l-0.232-0.415c-1.574-2.381-3.028-5.115-4.218-7.987l-0.119-0.325c-5.551-11.368-8.797-24.735-8.797-38.86 0-0.23 0.001-0.46 0.003-0.689v0.035c0-0.017 0-0.037 0-0.057 0-5.166 0.394-10.241 1.154-15.195l-0.070 0.554c-5.405-1.532-11.612-2.412-18.026-2.412-0.228 0-0.455 0.001-0.682 0.003h0.035zM877.026 84.781c-20.129 0.108-38.483 7.622-52.493 19.954l0.089-0.077c-14.994 12.543-25.212 30.362-27.788 50.568l-0.041 0.392c-0.537 3.145-0.844 6.769-0.844 10.463 0 0.091 0 0.182 0.001 0.273v-0.014c-0.001 0.109-0.001 0.239-0.001 0.368 0 12.484 2.89 24.293 8.038 34.794l-0.207-0.466c1.278 2.771 2.523 5.062 3.896 7.265l-0.161-0.278c7.898 12.884 18.884 23.175 31.958 30.024l0.449 0.214c0.692 0.493 1.491 0.902 2.346 1.186l0.064 0.018c10.065 4.991 21.914 7.922 34.445 7.951h0.010c0.046 0 0.1 0 0.154 0 7.802 0 15.336-1.144 22.444-3.275l-0.553 0.142c35.119-9.412 60.555-40.954 60.555-78.437 0-44.777-36.299-81.077-81.077-81.077-0.451 0-0.902 0.004-1.351 0.011l0.068-0.001zM906.059 183.206c9.581 0 17.348 7.767 17.348 17.348s-7.767 17.348-17.348 17.348v0c-0.002 0-0.004 0-0.007 0-9.411 0-17.072-7.495-17.341-16.841l-0.001-0.025c-0.004-0.12-0.006-0.262-0.006-0.404 0-1.849 0.356-3.615 1.003-5.232l-0.034 0.095-29.274-16.986c-3.089 3.105-7.328 5.063-12.025 5.18h-0.022c-9.003-0.772-16.019-8.271-16.019-17.408s7.015-16.636 15.954-17.404l0.065-0.004c4.719 0.117 8.958 2.075 12.046 5.179l0.001 0.001 12.047-7.228 16.504-9.638c-0.536-1.568-0.846-3.375-0.846-5.255 0-0.101 0.001-0.202 0.003-0.302v0.015c0-9.581 7.767-17.348 17.348-17.348s17.348 7.767 17.348 17.348c0 9.581-7.767 17.348-17.348 17.348v0c-5.563-0.038-10.508-2.653-13.705-6.709l-0.028-0.037-16.143 9.397-12.047 7.228c1.007 2.155 1.621 4.672 1.686 7.326v0.023c-0.052 2.758-0.667 5.36-1.736 7.712l0.050-0.122 28.672 16.625c3.116-4.367 8.151-7.19 13.848-7.228h0.006z" />
<glyph unicode="&#xe90d;" glyph-name="file" d="M843.294 54.182c0-2.063-1.672-3.735-3.735-3.735v0h-655.119c-2.063 0-3.735 1.672-3.735 3.735v0 787.637c0 2.063 1.672 3.735 3.735 3.735v0h454.054v60.235h-454.054c-35.33 0-63.97-28.64-63.97-63.97v-787.637c0-35.33 28.64-63.97 63.97-63.97v0h655.119c35.33 0 63.97 28.64 63.97 63.97v0 540.19h-60.235zM843.294 696.772l-174.2 209.016v-281.299h234.436l-60.235 72.282z" />
<glyph unicode="&#xe90e;" glyph-name="contacts" d="M875.339 905.788h-655.119c-35.174-0.205-63.608-28.766-63.608-63.969 0 0 0-0.001 0-0.001v0-56.501h28.672c26.614 0 48.188-21.575 48.188-48.188s-21.575-48.188-48.188-48.188v0h-28.672v-192.753h28.672c26.614 0 48.188-21.575 48.188-48.188s-21.575-48.188-48.188-48.188v0h-28.672v-192.753h28.672c26.614 0 48.188-21.575 48.188-48.188s-21.575-48.188-48.188-48.188v0h-28.672v-56.501c0-35.33 28.64-63.97 63.97-63.97v0h654.758c0.107-0.001 0.234-0.001 0.361-0.001 35.33 0 63.97 28.64 63.97 63.97 0 0 0 0.001 0 0.001v0 787.637c0 0 0 0.001 0 0.001 0 35.33-28.64 63.97-63.97 63.97-0.127 0-0.254 0-0.381-0.001h0.020zM730.775 255.247h-368.52c-0.024 0-0.053 0-0.081 0-9.98 0-18.071 8.090-18.071 18.071 0 1.409 0.161 2.781 0.467 4.098l-0.024-0.122c2.111 10.104 6.682 18.914 13.060 26.078l-0.049-0.056c15.661 16.023 78.788 32.045 110.11 48.188 18.94 10.401 31.565 30.213 31.565 52.974 0 0.139 0 0.277-0.001 0.415v-0.021c-1.093 10.266-5.776 19.271-12.751 25.884l-0.019 0.018c-5.568 6.842-10.036 14.847-12.974 23.556l-0.157 0.538c-10.94 4.714-18.46 15.404-18.46 27.85 0 1.053 0.054 2.094 0.159 3.119l-0.011-0.129c-0.097 1.030-0.152 2.228-0.152 3.439 0 7.656 2.211 14.795 6.029 20.814l-0.094-0.159c-1.566 10.722-2.891 22.167-3.735 33.491-0.652 4.066-1.025 8.753-1.025 13.527 0 13.019 2.772 25.391 7.758 36.557l-0.227-0.57c5.785 12.712 18.376 21.391 32.994 21.391 2.219 0 4.391-0.2 6.5-0.583l-0.221 0.033c2.986 9.996 9.527 18.143 18.123 23.149l0.189 0.102c13.975 6.987 112.76 10.481 114.206-85.173 0.143-1.265 0.225-2.731 0.225-4.216s-0.082-2.951-0.241-4.394l0.016 0.178c-0.843-11.324-2.048-22.648-3.614-33.491 3.737-5.787 5.958-12.858 5.958-20.448 0-1.284-0.064-2.553-0.188-3.805l0.013 0.158c0.094-0.897 0.148-1.937 0.148-2.991 0-12.446-7.52-23.136-18.264-27.774l-0.196-0.075c-3.173-9.234-7.632-17.229-13.254-24.252l0.122 0.158c-6.963-6.561-11.64-15.479-12.753-25.474l-0.017-0.187c-0.001-0.153-0.002-0.333-0.002-0.514 0-22.761 12.625-42.574 31.254-52.818l0.312-0.157c31.563-16.023 94.328-32.045 110.231-48.188 6.295-7.112 10.827-15.924 12.828-25.661l0.062-0.361c0.299-1.231 0.47-2.644 0.47-4.096 0-9.934-8.015-17.995-17.932-18.070h-0.007zM184.922 122.729c19.96 0 36.141 16.181 36.141 36.141s-16.181 36.141-36.141 36.141v0h-64.452c-19.96 0-36.141-16.181-36.141-36.141s16.181-36.141 36.141-36.141v0h64.090zM120.471 411.859h64.090c19.96 0 36.141 16.181 36.141 36.141s-16.181 36.141-36.141 36.141v0h-64.090c-19.96 0-36.141-16.181-36.141-36.141s16.181-36.141 36.141-36.141v0zM120.471 700.988h64.090c19.96 0 36.141 16.181 36.141 36.141s-16.181 36.141-36.141 36.141v0h-64.090c-19.96 0-36.141-16.181-36.141-36.141s16.181-36.141 36.141-36.141v0z" />
<glyph unicode="&#xe90f;" glyph-name="code" d="M839.56 905.788h-655.119c-35.33 0-63.97-28.64-63.97-63.97v-787.637c0-35.33 28.64-63.97 63.97-63.97v0h655.119c35.33 0 63.97 28.64 63.97 63.97v0 787.637c0 35.33-28.64 63.97-63.97 63.97v0zM843.294 54.182c0-2.063-1.672-3.735-3.735-3.735v0h-655.119c-2.063 0-3.735 1.672-3.735 3.735v0 787.637c0 2.063 1.672 3.735 3.735 3.735v0h655.119c2.063 0 3.735-1.672 3.735-3.735v0zM445.741 514.259c0 0.036 0 0.078 0 0.121 0 5.928-2.817 11.198-7.185 14.545l-0.044 0.032c-3.983 2.691-8.892 4.295-14.175 4.295-4.094 0-7.962-0.963-11.392-2.675l0.148 0.067-184.2-86.618c-8.222-3.631-13.857-11.713-13.857-21.111 0-0.117 0.001-0.234 0.003-0.351v0.018c-0.012-0.283-0.019-0.616-0.019-0.95 0-9.595 5.609-17.881 13.727-21.756l0.145-0.062 182.874-86.618c3.48-1.929 7.624-3.084 12.033-3.132h0.015c0.048 0 0.104-0.001 0.16-0.001 5.069 0 9.747 1.674 13.511 4.5l-0.058-0.042c4.41 3.332 7.23 8.565 7.23 14.458 0 0.084-0.001 0.168-0.002 0.252v-0.013c-0.071 7.753-4.57 14.439-11.087 17.657l-0.116 0.052-159.021 75.174 159.503 75.174c6.763 2.889 11.483 9.349 11.805 16.947l0.001 0.039zM593.92 607.503c0.002 0.105 0.003 0.229 0.003 0.352 0 5.748-2.249 10.971-5.915 14.836l0.009-0.010c-3.681 4.147-9.026 6.747-14.977 6.747-0.029 0-0.057 0-0.086 0h0.004c-9.851-0.020-18.105-6.831-20.33-16l-0.029-0.143-101.798-317.32c-0.832-2.21-1.355-4.765-1.445-7.429l-0.001-0.040c0-0.049-0.001-0.106-0.001-0.164 0-5.808 2.246-11.091 5.916-15.028l-0.012 0.013c3.716-4.077 9.049-6.626 14.977-6.626 0.029 0 0.058 0 0.086 0h-0.004c4.647 0.168 8.845 1.966 12.066 4.836l-0.019-0.017c3.378 2.964 5.926 6.796 7.301 11.149l0.048 0.175 102.28 317.199c0.984 2.183 1.668 4.715 1.92 7.372l0.007 0.097zM795.106 444.024l-183.236 86.618c-3.456 2.029-7.611 3.228-12.047 3.228-5.294 0-10.189-1.707-14.164-4.601l0.069 0.048c-4.553-3.371-7.472-8.724-7.472-14.758 0-0.106 0.001-0.211 0.003-0.316v0.016c0.315-7.802 5.137-14.404 11.919-17.299l0.128-0.049 158.901-74.812-159.985-75.535c-6.524-3.171-10.945-9.741-10.963-17.345v-0.002c-0.001-0.071-0.002-0.155-0.002-0.24 0-5.892 2.82-11.126 7.184-14.425l0.045-0.033c3.706-2.784 8.384-4.458 13.453-4.458 0.056 0 0.113 0 0.169 0.001h-0.009c0.189-0.005 0.412-0.008 0.636-0.008 4.169 0 8.098 1.028 11.547 2.844l-0.136-0.065 183.959 86.98c8.264 3.938 13.873 12.223 13.873 21.819 0 0.334-0.007 0.667-0.020 0.998l0.002-0.047c0.002 0.099 0.002 0.216 0.002 0.333 0 9.398-5.634 17.48-13.71 21.053l-0.147 0.058z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,9 +1,9 @@
@font-face {
font-family: 'cptools';
src:
url('fonts/cptools.ttf?dysqmo') format('truetype'),
url('fonts/cptools.woff?dysqmo') format('woff'),
url('fonts/cptools.svg?dysqmo#cptools') format('svg');
url('fonts/cptools.ttf?703wg5') format('truetype'),
url('fonts/cptools.woff?703wg5') format('woff'),
url('fonts/cptools.svg?703wg5#cptools') format('svg');
font-weight: normal;
font-style: normal;
}
@ -11,6 +11,7 @@
.cptools {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'cptools' !important;
display: inline-block;
speak: none;
font-style: normal;
font-weight: normal;
@ -23,6 +24,48 @@
-moz-osx-font-smoothing: grayscale;
}
.cptools-slide:before {
content: "\e902";
}
.cptools-shared-folder:before {
content: "\e903";
}
.cptools-poll:before {
content: "\e904";
}
.cptools-file-upload:before {
content: "\e905";
}
.cptools-whiteboard:before {
content: "\e906";
}
.cptools-todo:before {
content: "\e907";
}
.cptools-pad:before {
content: "\e908";
}
.cptools-folder-open:before {
content: "\e909";
}
.cptools-kanban:before {
content: "\e90a";
}
.cptools-folder:before {
content: "\e90b";
}
.cptools-shared-folder-open:before {
content: "\e90c";
}
.cptools-file:before {
content: "\e90d";
}
.cptools-contacts:before {
content: "\e90e";
}
.cptools-code:before {
content: "\e90f";
}
.cptools-template:before {
content: "\e900";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -191,7 +191,10 @@ define([
// load the user's object using the legacy credentials
loadUserObject(opt, waitFor(function (err, rt) {
if (err) { return void cb(err); }
if (err) {
waitFor.abort();
return void cb(err);
}
// if a proxy is marked as deprecated, it is because someone had a non-owned drive
// but changed their password, and couldn't delete their old data.
@ -199,6 +202,7 @@ define([
// allow them to proceed. In time, their old drive should get deleted, since
// it will should be pinned by anyone's drive.
if (rt.proxy[Constants.deprecatedKey]) {
waitFor.abort();
return void cb('NO_SUCH_USER', res);
}
@ -514,7 +518,22 @@ define([
if (testing) { return void proceed(result); }
proceed(result);
if (!(proxy.curvePrivate && proxy.curvePublic &&
proxy.edPrivate && proxy.edPublic)) {
console.log("recovering derived public/private keypairs");
// **** reset keys ****
proxy.curvePrivate = result.curvePrivate;
proxy.curvePublic = result.curvePublic;
proxy.edPrivate = result.edPrivate;
proxy.edPublic = result.edPublic;
}
setTimeout(function () {
Realtime.whenRealtimeSyncs(result.realtime, function () {
proceed(result);
});
});
});
}, 500);
}, 200);

View File

@ -1,8 +1,7 @@
define([
'jquery',
'/common/outer/local-store.js',
'/customize/messages.js',
], function ($, LocalStore, Messages) {
], function ($, LocalStore) {
$(function () {
var $main = $('#mainBlock');
@ -18,9 +17,6 @@ define([
window.location = '/drive/';
return;
}
$main.find('a[href="/drive/"] div.pad-button-text h4')
.text(Messages.main_yourCryptDrive);
}
$(window).click(function () {
$('.cp-dropdown-content').hide();

View File

@ -1,15 +1,12 @@
define([
'/api/config',
'/common/hyperscript.js',
'/common/common-language.js',
'/customize/messages.js',
'jquery',
'/customize/application_config.js',
], function (Config, h, Language, Msg, $, AppConfig) {
], function (h, Language, Msg, $) {
var Pages = {};
var urlArgs = Config.requireConf.urlArgs;
var setHTML = Pages.setHTML = function (e, html) {
Pages.setHTML = function (e, html) {
e.innerHTML = html;
return e;
};
@ -61,7 +58,7 @@ define([
return h('a', attrs, text);
};
var infopageFooter = function () {
Pages.infopageFooter = function () {
return h('footer', [
h('div.container', [
h('div.row', [
@ -94,11 +91,11 @@ define([
])
])
]),
h('div.cp-version-footer', "CryptPad v2.6.0 (Gibbon)")
h('div.cp-version-footer', "CryptPad v2.14.0 (Opossum)")
]);
};
var infopageTopbar = function () {
Pages.infopageTopbar = function () {
var rightLinks;
var username = window.localStorage.getItem('User_name');
if (username === null) {
@ -145,802 +142,5 @@ define([
);
};
Pages['/about.html'] = function () {
return h('div#cp-main', [
infopageTopbar(),
h('div.container-fluid.cp-about-intro', [
h('div.container', [
h('center', [
h('h1', Msg.about),
setHTML(h('p'), Msg.about_intro),
]),
]),
]),
h('div.container.cp-container', [
h('div.row', [
h('div.cp-develop-about.col-12',[
h('div.cp-icon-cent'),
h('h2.text-center', Msg.about_core)
]),
]),
h('div.row.align-items-center', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-bio-avatar', [
h('img.img-fluid', {'src': '/customize/images/CalebJames.jpg'})
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-profile-det', [
h('h3', "Caleb James Delisle"),
h('hr'),
setHTML(h('div#bioCaleb'), '<p>Caleb is a cryptography developer, Machine Technology graduate of the Franklin County Technical School and lifelong tinkerer.<br/>In 2011, he started the cjdns Open Source project to show that secure networking could be invisible and easily deployed.<br/>After joining XWiki SAS in 2014, he started the CryptPad project with the intent of bringing the same transparent security to collaborative editing.<br/>He\'s always trying to learn from more experienced colleagues and when someone passes through the Research Team office, his favorite words are "Pull up a chair!".</p>'),
h('a.cp-soc-media', { href : 'https://twitter.com/cjdelisle'}, [
h('i.fa.fa-twitter')
]),
h('a.cp-soc-media', { href : 'https://github.com/cjdelisle'}, [
h('i.fa.fa-github')
])
]),
]),
h('div.row.align-items-center',[
h('div.col-12.col-sm-12.col-md-12.col-lg-6.order-lg-2.cp-bio-avatar.cp-bio-avatar-right', [
h('img.img-fluid', {'src': '/customize/images/AaronMacSween.jpg'})
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.order-lg-1.cp-profile-det',[
h('h3', "Aaron MacSween"),
h('hr'),
setHTML(h('div#bioAaron'), '<p>Aaron transitioned into distributed systems development from a background in jazz and live stage performance. <br/> He appreciates the elegance of biological systems and functional programming, and focused on both as a student at the University of Toronto, where he studied cognitive and computer sciences.<br/>He moved to Paris in 2015 to work as a research engineer at XWiki SAS, after having dedicated significant time to various cryptography-related software projects.<br/>He spends his spare time experimenting with guitars, photography, science fiction, and spicy food.</p>'),
h('a.cp-soc-media', { href : 'https://twitter.com/fc00ansuz'}, [
h('i.fa.fa-twitter')
]),
h('a.cp-soc-media', { href : 'https://github.com/ansuz/'}, [
h('i.fa.fa-github')
])
]),
]),
h('div.row.align-items-center', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-bio-avatar', [
h('img.img-fluid', {'src': '/customize/images/YannFlory.jpg'})
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-profile-det', [
h('h3', "Yann Flory"),
h('hr'),
setHTML(h('div#bioYann'), '<p>In 2015, Yann graduated with an engineering degree from Ecole Centrale de Lille majoring in Data Science. In his studies he worked on a project to detect defects in optical fiber using image processing technology.<br/>Upon joining XWiki SAS, Yann developed a Wiki page recommendation system, a common API for accessing data server-side and client-side, and an integrated development environment for development of XWiki applications.<br/>Yann is soft spoken but brutally efficient, he is known to say "It will take 5 minutes".</p>'),
h('a.cp-soc-media', { href : 'https://github.com/yflory/'}, [
h('i.fa.fa-github')
])
]),
]),
h('div.row', [
h('div.cp-develop-about.col-12.cp-contrib',[
h('div.cp-icon-cent'),
h('h2.text-center', Msg.about_contributors)
]),
]),
h('div.row.align-items-center', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-bio-avatar', [
h('img.img-fluid', {'src': '/customize/images/Pierre-new.jpg'})
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-profile-det', [
h('h3', "Pierre Bondoerffer"),
h('hr'),
setHTML(h('div#bioPierre'), '<p>Resident CSS wizard and emoji extraordinaire, Pierre is passionate about anything related to technology. He loves to hack around computers and put parts together.<br/>He is currently studying at 42, where he learns about algorithms, networking, kernel programming and graphics.<br/>As a part of an internship, he joined XWiki SAS and worked on CryptPad to improve user experience. He also maintains the Spanish translation.</p>'),
h('a.cp-soc-media', { href : 'https://twitter.com/pbondoer'}, [
h('i.fa.fa-twitter')
]),
h('a.cp-soc-media', { href : 'https://github.com/pbondoer'}, [
h('i.fa.fa-github')
])
]),
]),
h('div.row.align-items-center',[
h('div.col-12.col-sm-12.col-md-12.col-lg-6.order-lg-2.cp-bio-avatar.cp-bio-avatar-right', [
h('img.img-fluid', {'src': '/customize/images/Catalin.jpg'})
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.order-lg-1.cp-profile-det',[
h('h3', "Catalin Scripcariu"),
h('hr'),
setHTML(h('div#bioCatalin'), '<p> Catalin is a Maths majour and has worked in B2B sales for 12 years. Design was always his passion and 3 years ago he started to dedicate himself to web design and front-end.<br/>At the beginning of 2017 he joined the XWiki, where he worked both on the business and the community side of XWiki, including the research team and CryptPad. </p>'),
h('a.cp-soc-media', { href : 'https://twitter.com/catalinscr'}, [
h('i.fa.fa-twitter')
]),
h('a.cp-soc-media', { href : 'https://www.linkedin.com/in/catalinscripcariu/'}, [
h('i.fa.fa-linkedin')
])
]),
]),
h('div.row.align-items-center.cp-margin-bot', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-bio-avatar', [
h('img.img-fluid', {'src': '/customize/images/LudovicDuboist.jpg'})
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-profile-det', [
h('h3', "Ludovic Dubost"),
h('hr'),
setHTML(h('div#bioLudovic'), '<p>A graduate of PolyTech (X90) and Telecom School in Paris, Ludovic Dubost started his career as a software architect for Netscape Communications Europe. He then became CTO of NetValue, one of the first French start-ups that went public. He left NetValue after the company was purchased by Nielsen/NetRatings and in 2004 launched XWiki, the next generation wiki.<br/>Since the very beginning, Ludovic has been immensely helpful to the CryptPad project. He believed in the idea when there was nothing more than the collaborative pad and his help with sales strategy for the project.</p>'),
h('a.cp-soc-media', { href : 'https://twitter.com/ldubost'}, [
h('i.fa.fa-twitter')
]),
h('a.cp-soc-media', { href : 'https://github.com/ldubost'}, [
h('i.fa.fa-github')
])
]),
]),
]),
infopageFooter()
]);
};
Pages['/features.html'] = function () {
return h('div#cp-main', [
infopageTopbar(),
h('div.container-fluid.cp_cont_features',[
h('div.container',[
h('center', h('h1', Msg.features_title)),
]),
]),
h('div.container',[
h('div.row.cp-container.cp-features-web.justify-content-sm-center',[
h('div.col-12.col-sm-6.cp-anon-user',[
h('div.card',[
h('div.card-body',[
h('h3.text-center',Msg.features_anon)
]),
h('ul.list-group.list-group-flush', [
h('li.list-group-item.text-center', Msg.features_f_pad , [
h('a.voted', {href: '#', 'data-toggle' : 'tooltip', 'data-placement': 'bottom', title : Msg.features_f_pad_notes}, h('i.fa.fa-question'))
]),
h('li.list-group-item.text-center', Msg.features_f_history, [
h('a.voted', {href: '#', 'data-toggle' : 'tooltip', 'data-placement': 'bottom', title : Msg.features_f_history_notes }, h('i.fa.fa-question') )
]),
h('li.list-group-item.text-center', Msg.features_f_export, [
h('a.voted', {href: '#', 'data-toggle' : 'tooltip', 'data-placement': 'bottom', title : Msg.features_f_export_notes }, h('i.fa.fa-question'))
]),
h('li.list-group-item.text-center', Msg.features_f_todo),
h('li.list-group-item.text-center', Msg.features_f_viewFiles),
h('li.list-group-item.text-center', Msg.features_f_drive),
h('li.list-group-item.text-center', Msg.features_f_storage_anon),
]),
]),
]),
h('div.col-12.col-sm-6.cp-regis-user',[
h('div.card',[
h('div.card-body',[
h('h3.text-center',Msg.features_registered)
]),
h('ul.list-group.list-group-flush', [
h('li.list-group-item.text-center', Msg.features_f_pad, [
h('a.voted', {href: '#', 'data-toggle' : 'tooltip', 'data-placement': 'bottom', title : Msg.features_f_pad_notes}, h('i.fa.fa-question'))
]),
h('li.list-group-item.text-center', Msg.features_f_history, [
h('a.voted', {href: '#', 'data-toggle' : 'tooltip', 'data-placement': 'bottom', title : Msg.features_f_history_notes }, h('i.fa.fa-question'))
]),
h('li.list-group-item.text-center', Msg.features_f_export, [
h('a.voted', {href: '#', 'data-toggle' : 'tooltip', 'data-placement': 'bottom', title : Msg.features_f_export_notes }, h('i.fa.fa-question'))
]),
h('li.list-group-item.text-center', Msg.features_f_todo),
h('li.list-group-item.text-center', Msg.features_f_viewFiles),
h('li.list-group-item.text-center', Msg.features_f_drive_full),
h('li.list-group-item.text-center', Msg.features_f_uploadFiles),
h('li.list-group-item.text-center', Msg.features_f_embedFiles),
h('li.list-group-item.text-center', Msg.features_f_multiple, [
h('a.voted', {href: '#', 'data-toggle' : 'tooltip', 'data-placement': 'bottom', title : Msg.features_f_multiple_notes }, h('i.fa.fa-question'))
]),
h('li.list-group-item.text-center', Msg.features_f_logoutEverywhere),
h('li.list-group-item.text-center', Msg.features_f_templates, [
h('a.voted', {href: '#', 'data-toggle' : 'tooltip', 'data-placement': 'bottom', title : Msg.features_f_templates_notes }, h('i.fa.fa-question'))
]),
h('li.list-group-item.text-center', Msg.features_f_profile, [
h('a.voted', {href: '#', 'data-toggle' : 'tooltip', 'data-placement': 'bottom', title : Msg.features_f_profile_notes }, h('i.fa.fa-question'))
]),
h('li.list-group-item.text-center', Msg.features_f_tags, [
h('a.voted', {href: '#', 'data-toggle' : 'tooltip', 'data-placement': 'bottom', title : Msg.features_f_tags_notes }, h('i.fa.fa-question'))
]),
h('li.list-group-item.text-center', Msg.features_f_contacts, [
h('a.voted', {href: '#', 'data-toggle' : 'tooltip', 'data-placement': 'bottom', title : Msg.features_f_contacts_notes }, h('i.fa.fa-question'))
]),
h('li.list-group-item.text-center', setHTML(h('div'), Msg.features_f_storage_registered)),
]),
h('div.card-body',[
h('div#cp-features-register', [
h('a', {
href: '/register/'
}, h('button.cp-features-register-button', Msg.features_f_register))
]),
]),
]),
]),
]),
]),
infopageFooter()
]);
};
Pages['/privacy.html'] = function () {
return h('div#cp-main', [
infopageTopbar(),
h('.container-fluid.cp-privacy-top', [
h('div.container',[
h('center', h('h1', Msg.policy_title)),
]),
]),
h('div.container.cp-container.cp-privacy',[
h('h3', Msg.policy_whatweknow),
h('hr'),
setHTML(h('p'), Msg.policy_whatweknow_p1),
h('h3', Msg.policy_howweuse),
h('hr'),
h('p', Msg.policy_howweuse_p1),
h('p', Msg.policy_howweuse_p2),
h('h3', Msg.policy_whatwetell),
h('hr'),
h('p', Msg.policy_whatwetell_p1),
h('h3', Msg.policy_links),
h('hr'),
h('p', Msg.policy_links_p1),
h('h3', Msg.policy_ads),
h('hr'),
h('p', Msg.policy_ads_p1),
h('h3', Msg.policy_choices),
h('hr'),
h('p', Msg.policy_choices_open),
setHTML(h('p'), Msg.policy_choices_vpn),
]),
infopageFooter()
]);
};
Pages['/faq.html'] = function () {
var categories = [];
var faq = Msg.faq;
Object.keys(faq).forEach(function (c) {
var questions = [];
Object.keys(faq[c]).forEach(function (q) {
var item = faq[c][q];
if (typeof item !== "object") { return; }
var answer = h('p.cp-faq-questions-a');
var hash = c + '-' + q;
var question = h('p.cp-faq-questions-q#' + hash);
$(question).click(function () {
if ($(answer).is(':visible')) {
$(question).toggleClass('cp-active-faq');
return void $(answer).slideUp();
}
$(question).toggleClass('cp-active-faq');
$(answer).slideDown();
});
questions.push(h('div.cp-faq-questions-items', [
setHTML(question, item.q),
setHTML(answer, item.a)
]));
});
categories.push(h('div.cp-faq-category', [
h('h3', faq[c].title),
h('div.cp-faq-category-questions', questions)
]));
});
var hash = window.location.hash;
if (hash) {
$(categories).find(hash).click();
}
return h('div#cp-main', [
infopageTopbar(),
h('div.container-fluid.cp-faq', [
h('div.container',[
h('center', h('h1', Msg.faq_title)),
]),
]),
h('div.container.cp-faq-ques-det',[
h('div.cp-faq-header.text-center', h('a.nav-item.nav-link', {
href: '/what-is-cryptpad.html'
}, setHTML(h('h4'),Msg.faq_whatis))),
h('div.cp-faq-container', categories)
]),
infopageFooter()
]);
};
Pages['/terms.html'] = function () {
return h('div#cp-main', [
infopageTopbar(),
h('div.container.cp-container', [
h('center', h('h1', Msg.tos_title)),
h('p', Msg.tos_legal),
h('p', Msg.tos_availability),
h('p', Msg.tos_e2ee),
h('p', Msg.tos_logs),
h('p', Msg.tos_3rdparties),
]),
infopageFooter()
]);
};
Pages['/contact.html'] = function () {
return h('div#cp-main', [
infopageTopbar(),
h('div.container-fluid.cp-contdet', [
h('row.col-12.col-sm-12',
h('h1.text-center', Msg.contact )
)
]),
h('div.container.cp-container', [
h('div.row.cp-iconCont.align-items-center', [
h('div.col-12',
setHTML(h('h4.text-center'), Msg.main_about_p26)
),
h('div.col-12.col-sm-6.col-md-3.col-lg-3',
h('a.card', {href : "https://twitter.com/cryptpad"},
h('div.card-body',
setHTML(h('p'), Msg.main_about_p22)
)
)
),
h('div.col-12.col-sm-6.col-md-3.col-lg-3',
h('a.card', {href : "https://github.com/xwiki-labs/cryptpad/issues/"},
h('div.card-body',
setHTML(h('p'), Msg.main_about_p23)
)
)
),
h('div.col-12.col-sm-6.col-md-3.col-lg-3',
h('a.card', {href : "https://riot.im/app/#/room/#cryptpad:matrix.org"},
h('div.card-body',
setHTML(h('p'), Msg.main_about_p24)
)
)
),
h('div.col-12.col-sm-6.col-md-3.col-lg-3',
h('a.card', {href : "mailto:research@xwiki.com"},
h('div.card-body',
setHTML(h('p'), Msg.main_about_p25)
)
)
),
]),
]),
infopageFooter(),
]);
};
Pages['/what-is-cryptpad.html'] = function () {
return h('div#cp-main', [
infopageTopbar(),
h('div.container-fluid.cp-what-is',[
h('div.container',[
h('div.row',[
h('div.col-12.text-center', h('h1', Msg.whatis_title)),
]),
]),
]),
h('div.container.cp-container', [
h('div.row.align-items-center', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6', [
setHTML(h('h2'), Msg.whatis_collaboration),
setHTML(h('p'), Msg.whatis_collaboration_p1),
setHTML(h('p'), Msg.whatis_collaboration_p2),
setHTML(h('p'), Msg.whatis_collaboration_p3),
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6', [
h('img', { src: '/customize/images/pad_screenshot.png?' + urlArgs }),
]),
]),
h('div.row.align-items-center', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6.order-2', [
setHTML(h('h2'), Msg.whatis_zeroknowledge),
setHTML(h('p'), Msg.whatis_zeroknowledge_p1),
setHTML(h('p'), Msg.whatis_zeroknowledge_p2),
setHTML(h('p'), Msg.whatis_zeroknowledge_p3),
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.order-1', [
h('img#zeroknowledge', { src: '/customize/images/zeroknowledge_small.png?' + urlArgs }),
]),
]),
h('div.row.align-items-center', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6', [
setHTML(h('h2'), Msg.whatis_drive),
setHTML(h('p'), Msg.whatis_drive_p1),
setHTML(h('p'), Msg.whatis_drive_p2),
setHTML(h('p'), Msg.whatis_drive_p3),
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6', [
h('img', { src: '/customize/images/drive_screenshot.png?' + urlArgs }),
]),
]),
h('div.row.align-items-center', [
h('div.col-12', [
setHTML(h('h2.text-center'), Msg.whatis_business),
setHTML(h('p'), Msg.whatis_business_p1),
setHTML(h('p'), Msg.whatis_business_p2),
]),
]),
]),
infopageFooter(),
]);
};
var isAvailableType = function (x) {
if (!Array.isArray(AppConfig.availablePadTypes)) { return true; }
return AppConfig.availablePadTypes.some(function (type) {
return x.indexOf(type) > -1;
});
};
Pages['/'] = Pages['/index.html'] = function () {
var showingMore = false;
var icons = [
[ 'pad', '/pad/', Msg.main_richTextPad, 'pad' ],
[ 'code', '/code/', Msg.main_codePad, 'code' ],
[ 'slide', '/slide/', Msg.main_slidePad, 'slide' ],
[ 'poll', '/poll/', Msg.main_pollPad, 'poll' ],
[ 'kanban', '/kanban/', Msg.main_kanbanPad, 'kanban' ],
[ 'whiteboard', '/whiteboard/', Msg.main_whiteboardPad, 'whiteboard' ],
[ 'recent', '/drive/', Msg.main_localPads, 'drive' ]
].filter(function (x) {
return isAvailableType(x[1]);
})
.map(function (x, i) {
var s = 'div.bs-callout.cp-callout-' + x[0];
if (i > 2) { s += '.cp-more.cp-hidden'; }
return h('a', [
{ href: x[1] },
h(s, [
h('i.fa.' + AppConfig.applicationsIcon[x[3]]),
h('div.pad-button-text', [ h('h4', x[2]) ])
])
]);
});
var more = icons.length < 4? undefined: h('div.bs-callout.cp-callout-more', [
h('div.cp-callout-more-lessmsg.cp-hidden', [
"see less ",
h('i.fa.fa-caret-up')
]),
h('div.cp-callout-more-moremsg', [
"see more ",
h('i.fa.fa-caret-down')
]),
{
onclick: function () {
if (showingMore) {
$('.cp-more, .cp-callout-more-lessmsg').addClass('cp-hidden');
$('.cp-callout-more-moremsg').removeClass('cp-hidden');
} else {
$('.cp-more, .cp-callout-more-lessmsg').removeClass('cp-hidden');
$('.cp-callout-more-moremsg').addClass('cp-hidden');
}
showingMore = !showingMore;
}
}
]);
return [
h('div#cp-main', [
infopageTopbar(),
h('div.container.cp-container', [
h('div.row', [
h('div.cp-title.col-12.col-sm-6', [
h('img', { src: '/customize/cryptpad-new-logo-colors-logoonly.png?' + urlArgs }),
h('h1', 'CryptPad'),
h('p', Msg.main_catch_phrase)
]),
h('div.col-12.col-sm-6', [
icons,
more
])
])
]),
]),
infopageFooter(),
];
};
Pages.createCheckbox = function (id, labelTxt, checked, opts) {
opts = opts|| {};
// Input properties
var inputOpts = {
type: 'checkbox',
id: id
};
if (checked) { inputOpts.checked = 'checked'; }
$.extend(inputOpts, opts.input || {});
// Label properties
var labelOpts = {};
$.extend(labelOpts, opts.label || {});
if (labelOpts.class) { labelOpts.class += ' cp-checkmark'; }
// Mark properties
var markOpts = { tabindex: 0 };
$.extend(markOpts, opts.mark || {});
var input = h('input', inputOpts);
var mark = h('span.cp-checkmark-mark', markOpts);
var label = h('span.cp-checkmark-label', labelTxt);
$(mark).keydown(function (e) {
if (e.which === 32) {
e.stopPropagation();
e.preventDefault();
$(input).prop('checked', !$(input).is(':checked'));
$(input).change();
}
});
$(input).change(function () { $(mark).focus(); });
return h('label.cp-checkmark', labelOpts, [
input,
mark,
label
]);
};
Pages.createRadio = function (name, id, labelTxt, checked, opts) {
opts = opts|| {};
// Input properties
var inputOpts = {
type: 'radio',
id: id,
name: name
};
if (checked) { inputOpts.checked = 'checked'; }
$.extend(inputOpts, opts.input || {});
// Label properties
var labelOpts = {};
$.extend(labelOpts, opts.label || {});
if (labelOpts.class) { labelOpts.class += ' cp-checkmark'; }
// Mark properties
var markOpts = { tabindex: 0 };
$.extend(markOpts, opts.mark || {});
var input = h('input', inputOpts);
var mark = h('span.cp-radio-mark', markOpts);
var label = h('span.cp-checkmark-label', labelTxt);
$(mark).keydown(function (e) {
if (e.which === 32) {
e.stopPropagation();
e.preventDefault();
$(input).prop('checked', !$(input).is(':checked'));
$(input).change();
}
});
$(input).change(function () { $(mark).focus(); });
var radio = h('label', labelOpts, [
input,
mark,
label
]);
$(radio).addClass('cp-radio');
return radio;
};
Pages['/user/'] = Pages['/user/index.html'] = function () {
return h('div#container');
};
Pages['/register/'] = Pages['/register/index.html'] = function () {
return [h('div#cp-main', [
infopageTopbar(),
h('div.container-fluid.cp-register-wel',[
h('div.container',[
h('div.row',[
h('div.col-12',[
h('h1.text-center', Msg.register_header)
])
])
])
]),
h('div.container.cp-container', [
h('div.row.cp-register-det', [
h('div#data.hidden.col-md-6', [
setHTML(h('p.register-explanation'), Msg.register_explanation)
]),
h('div#userForm.form-group.hidden.col-md-6', [
h('a', {
href: '/features.html'
}, Msg.register_whyRegister),
h('input.form-control#username', {
type: 'text',
autocomplete: 'off',
autocorrect: 'off',
autocapitalize: 'off',
spellcheck: false,
placeholder: Msg.login_username,
autofocus: true,
}),
h('input.form-control#password', {
type: 'password',
placeholder: Msg.login_password,
}),
h('input.form-control#password-confirm', {
type: 'password',
placeholder: Msg.login_confirm,
}),
h('div.checkbox-container', [
Pages.createCheckbox('import-recent', Msg.register_importRecent, true)
]),
h('div.checkbox-container', [
$(Pages.createCheckbox('accept-terms')).find('.cp-checkmark-label').append(Msg.register_acceptTerms).parent()[0]
]),
h('button#register.btn.cp-login-register', Msg.login_register)
])
]),
h('div.row.cp-register-test',[
h('hr'),
h('div.col-12', [
setHTML(h('p.test-details'), " \"Tools like Etherpad and Google Docs [...] all share a weakness, which is that whomever owns the document server can see everything you're typing. Cryptpad is a free/open project that uses some of the ideas behind blockchain to implement a \"zero-knowledge\" version of a collaborative document editor, ensuring that only the people working on a document can see it.\" "),
h('a.cp-test-source.pull-right', { href : 'http://boingboing.net/2016/09/26/cryptpad-a-freeopen-end-to.html'}, "Cory Doctorow")
])
])
]),
infopageFooter(),
])];
};
Pages['/login/'] = Pages['/login/index.html'] = function () {
return [h('div#cp-main', [
infopageTopbar(),
h('div.container.cp-container', [
h('div.row.align-items-center', [
h('div#data.hidden.col-md-6', setHTML(h('p.left'), Msg.main_info)),
h('div#userForm.form-group.hidden.col-md-6', [
h('input.form-control#name', {
name: 'name',
type: 'text',
autocomplete: 'off',
autocorrect: 'off',
autocapitalize: 'off',
spellcheck: false,
placeholder: Msg.login_username,
autofocus: true,
}),
h('input.form-control#password', {
type: 'password',
'name': 'password',
placeholder: Msg.login_password,
}),
h('div.checkbox-container', [
Pages.createCheckbox('import-recent', Msg.register_importRecent, true),
]),
h('div.extra', [
h('button.login.first.btn', Msg.login_login)
])
])
]),
]),
infopageFooter(),
])];
};
var appToolbar = function () {
return h('div#cp-toolbar.cp-toolbar-container');
};
Pages['/whiteboard/'] = Pages['/whiteboard/index.html'] = function () {
return [
appToolbar(),
h('div#cp-app-whiteboard-canvas-area',
h('div#cp-app-whiteboard-container',
h('canvas#cp-app-whiteboard-canvas', {
width: 600,
height: 600
})
)
),
h('div#cp-app-whiteboard-controls', {
style: {
display: 'block',
}
}, [
h('button#cp-app-whiteboard-clear.btn.btn-danger', Msg.canvas_clear), ' ',
h('button#cp-app-whiteboard-toggledraw.btn.btn-secondary', Msg.canvas_disable),
h('button#cp-app-whiteboard-delete.btn.btn-secondary', {
style: {
display: 'none',
}
}, Msg.canvas_delete),
h('div.cp-app-whiteboard-range-group', [
h('label', {
'for': 'cp-app-whiteboard-width'
}, Msg.canvas_width),
h('input#cp-app-whiteboard-width', {
type: 'range',
min: "1",
max: "100"
}),
h('span#cp-app-whiteboard-width-val', '5px')
]),
h('div.cp-app-whiteboard-range-group', [
h('label', {
'for': 'cp-app-whiteboard-opacity',
}, Msg.canvas_opacity),
h('input#cp-app-whiteboard-opacity', {
type: 'range',
min: "0.1",
max: "1",
step: "0.1"
}),
h('span#cp-app-whiteboard-opacity-val', '100%')
]),
h('span.cp-app-whiteboard-selected.cp-app-whiteboard-unselectable', [
h('img', {
title: Msg.canvas_currentBrush
})
])
]),
setHTML(h('div#cp-app-whiteboard-colors'), '&nbsp;'),
h('div#cp-app-whiteboard-cursors', {
style: {
display: 'none',
background: 'white',
'text-align': 'center',
}
}),
h('div#cp-app-whiteboard-pickers'),
h('div#cp-app-whiteboard-media-hidden')
];
};
Pages['/poll/'] = Pages['/poll/index.html'] = function () {
return [
appToolbar(),
h('div#cp-app-poll-content', [
h('div#cp-app-poll-form', [
h('div.cp-app-poll-realtime', [
h('br'),
h('div', [
h('textarea#cp-app-poll-description', {
rows: "5",
cols: "50",
placeholder: Msg.poll_descriptionHint,
disabled: true
}),
h('div#cp-app-poll-description-published'),
h('br')
]),
h('div#cp-app-poll-table-container', [
h('div#cp-app-poll-table-scroll', [h('table')]),
h('button#cp-app-poll-create-user.btn.btn-secondary', {
title: Msg.poll_create_user
}, Msg.poll_commit),
h('button#cp-app-poll-create-option.btn.btn-secondary', {
title: Msg.poll_create_option
}, h('span.fa.fa-plus')),
]),
h('div#cp-app-poll-comments', [
h('h2#cp-app-poll-comments-add-title', Msg.poll_comment_add),
h('div#cp-app-poll-comments-add', [
h('input.cp-app-poll-comments-add-name', {
type: 'text',
placeholder: Msg.anonymous
}),
h('textarea.cp-app-poll-comments-add-msg', {
placeholder: Msg.poll_comment_placeholder
}),
h('button.cp-app-poll-comments-add-submit.btn.btn-secondary',
Msg.poll_comment_submit),
h('button.cp-app-poll-comments-add-cancel.btn.btn-secondary',
Msg.cancel)
]),
h('h2#cp-app-poll-comments-list-title', Msg.poll_comment_list),
h('div#cp-app-poll-comments-list')
]),
h('div#cp-app-poll-nocomments', Msg.poll_comment_disabled)
])
])
])
];
};
return Pages;
});

View File

@ -0,0 +1,128 @@
define([
'/common/hyperscript.js',
'/customize/messages.js',
'/customize/pages.js'
], function (h, Msg, Pages) {
return function () {
return h('div#cp-main', [
Pages.infopageTopbar(),
h('div.container-fluid.cp-about-intro', [
h('div.container', [
h('center', [
h('h1', Msg.about),
Pages.setHTML(h('p'), Msg.about_intro),
]),
]),
]),
h('div.container.cp-container', [
h('div.row', [
h('div.cp-develop-about.col-12',[
h('div.cp-icon-cent'),
h('h2.text-center', Msg.about_core)
]),
]),
h('div.row.align-items-center', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-bio-avatar', [
h('img.img-fluid', {'src': '/customize/images/CalebJames.jpg'})
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-profile-det', [
h('h3', "Caleb James Delisle"),
h('hr'),
Pages.setHTML(h('div#bioCaleb'), '<p>Caleb is a cryptography developer, Machine Technology graduate of the Franklin County Technical School and lifelong tinkerer.<br/>In 2011, he started the cjdns Open Source project to show that secure networking could be invisible and easily deployed.<br/>After joining XWiki SAS in 2014, he started the CryptPad project with the intent of bringing the same transparent security to collaborative editing.<br/>He\'s always trying to learn from more experienced colleagues and when someone passes through the Research Team office, his favorite words are "Pull up a chair!".</p>'),
h('a.cp-soc-media', { href : 'https://twitter.com/cjdelisle'}, [
h('i.fa.fa-twitter')
]),
h('a.cp-soc-media', { href : 'https://github.com/cjdelisle'}, [
h('i.fa.fa-github')
])
]),
]),
h('div.row.align-items-center',[
h('div.col-12.col-sm-12.col-md-12.col-lg-6.order-lg-2.cp-bio-avatar.cp-bio-avatar-right', [
h('img.img-fluid', {'src': '/customize/images/AaronMacSween.jpg'})
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.order-lg-1.cp-profile-det',[
h('h3', "Aaron MacSween"),
h('hr'),
Pages.setHTML(h('div#bioAaron'), '<p>Aaron transitioned into distributed systems development from a background in jazz and live stage performance. <br/> He appreciates the elegance of biological systems and functional programming, and focused on both as a student at the University of Toronto, where he studied cognitive and computer sciences.<br/>He moved to Paris in 2015 to work as a research engineer at XWiki SAS, after having dedicated significant time to various cryptography-related software projects.<br/>He spends his spare time experimenting with guitars, photography, science fiction, and spicy food.</p>'),
h('a.cp-soc-media', { href : 'https://twitter.com/fc00ansuz'}, [
h('i.fa.fa-twitter')
]),
h('a.cp-soc-media', { href : 'https://github.com/ansuz/'}, [
h('i.fa.fa-github')
])
]),
]),
h('div.row.align-items-center', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-bio-avatar', [
h('img.img-fluid', {'src': '/customize/images/YannFlory.jpg'})
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-profile-det', [
h('h3', "Yann Flory"),
h('hr'),
Pages.setHTML(h('div#bioYann'), '<p>In 2015, Yann graduated with an engineering degree from Ecole Centrale de Lille majoring in Data Science. In his studies he worked on a project to detect defects in optical fiber using image processing technology.<br/>Upon joining XWiki SAS, Yann developed a Wiki page recommendation system, a common API for accessing data server-side and client-side, and an integrated development environment for development of XWiki applications.<br/>Yann is soft spoken but brutally efficient, he is known to say "It will take 5 minutes".</p>'),
h('a.cp-soc-media', { href : 'https://github.com/yflory/'}, [
h('i.fa.fa-github')
])
]),
]),
h('div.row', [
h('div.cp-develop-about.col-12.cp-contrib',[
h('div.cp-icon-cent'),
h('h2.text-center', Msg.about_contributors)
]),
]),
h('div.row.align-items-center', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-bio-avatar', [
h('img.img-fluid', {'src': '/customize/images/Pierre-new.jpg'})
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-profile-det', [
h('h3', "Pierre Bondoerffer"),
h('hr'),
Pages.setHTML(h('div#bioPierre'), '<p>Resident CSS wizard and emoji extraordinaire, Pierre is passionate about anything related to technology. He loves to hack around computers and put parts together.<br/>He is currently studying at 42, where he learns about algorithms, networking, kernel programming and graphics.<br/>As a part of an internship, he joined XWiki SAS and worked on CryptPad to improve user experience. He also maintains the Spanish translation.</p>'),
h('a.cp-soc-media', { href : 'https://twitter.com/pbondoer'}, [
h('i.fa.fa-twitter')
]),
h('a.cp-soc-media', { href : 'https://github.com/pbondoer'}, [
h('i.fa.fa-github')
])
]),
]),
h('div.row.align-items-center',[
h('div.col-12.col-sm-12.col-md-12.col-lg-6.order-lg-2.cp-bio-avatar.cp-bio-avatar-right', [
h('img.img-fluid', {'src': '/customize/images/Catalin.jpg'})
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.order-lg-1.cp-profile-det',[
h('h3', "Catalin Scripcariu"),
h('hr'),
Pages.setHTML(h('div#bioCatalin'), '<p> Catalin is a Maths majour and has worked in B2B sales for 12 years. Design was always his passion and 3 years ago he started to dedicate himself to web design and front-end.<br/>At the beginning of 2017 he joined the XWiki, where he worked both on the business and the community side of XWiki, including the research team and CryptPad. </p>'),
h('a.cp-soc-media', { href : 'https://twitter.com/catalinscr'}, [
h('i.fa.fa-twitter')
]),
h('a.cp-soc-media', { href : 'https://www.linkedin.com/in/catalinscripcariu/'}, [
h('i.fa.fa-linkedin')
])
]),
]),
h('div.row.align-items-center.cp-margin-bot', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-bio-avatar', [
h('img.img-fluid', {'src': '/customize/images/LudovicDuboist.jpg'})
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.cp-profile-det', [
h('h3', "Ludovic Dubost"),
h('hr'),
Pages.setHTML(h('div#bioLudovic'), '<p>A graduate of PolyTech (X90) and Telecom School in Paris, Ludovic Dubost started his career as a software architect for Netscape Communications Europe. He then became CTO of NetValue, one of the first French start-ups that went public. He left NetValue after the company was purchased by Nielsen/NetRatings and in 2004 launched XWiki, the next generation wiki.<br/>Since the very beginning, Ludovic has been immensely helpful to the CryptPad project. He believed in the idea when there was nothing more than the collaborative pad and his help with sales strategy for the project.</p>'),
h('a.cp-soc-media', { href : 'https://twitter.com/ldubost'}, [
h('i.fa.fa-twitter')
]),
h('a.cp-soc-media', { href : 'https://github.com/ldubost'}, [
h('i.fa.fa-github')
])
]),
]),
]),
Pages.infopageFooter()
]);
};
});

View File

@ -0,0 +1,53 @@
define([
'/common/hyperscript.js',
'/customize/messages.js',
'/customize/pages.js'
], function (h, Msg, Pages) {
return function () {
return h('div#cp-main', [
Pages.infopageTopbar(),
h('div.container-fluid.cp-contdet', [
h('row.col-12.col-sm-12',
h('h1.text-center', Msg.contact )
)
]),
h('div.container.cp-container', [
h('div.row.cp-iconCont.align-items-center', [
h('div.col-12',
Pages.setHTML(h('h4.text-center'), Msg.main_about_p26)
),
h('div.col-12.col-sm-6.col-md-3.col-lg-3',
h('a.card', {href : "https://twitter.com/cryptpad"},
h('div.card-body',
Pages.setHTML(h('p'), Msg.main_about_p22)
)
)
),
h('div.col-12.col-sm-6.col-md-3.col-lg-3',
h('a.card', {href : "https://github.com/xwiki-labs/cryptpad/issues/"},
h('div.card-body',
Pages.setHTML(h('p'), Msg.main_about_p23)
)
)
),
h('div.col-12.col-sm-6.col-md-3.col-lg-3',
h('a.card', {href : "https://riot.im/app/#/room/#cryptpad:matrix.org"},
h('div.card-body',
Pages.setHTML(h('p'), Msg.main_about_p24)
)
)
),
h('div.col-12.col-sm-6.col-md-3.col-lg-3',
h('a.card', {href : "mailto:research@xwiki.com"},
h('div.card-body',
Pages.setHTML(h('p'), Msg.main_about_p25)
)
)
),
]),
]),
Pages.infopageFooter(),
]);
};
});

View File

@ -0,0 +1,61 @@
define([
'jquery',
'/common/hyperscript.js',
'/customize/messages.js',
'/customize/pages.js'
], function ($, h, Msg, Pages) {
return function () {
var categories = [];
var faq = Msg.faq;
Object.keys(faq).forEach(function (c) {
var questions = [];
Object.keys(faq[c]).forEach(function (q) {
var item = faq[c][q];
if (typeof item !== "object") { return; }
var answer = h('p.cp-faq-questions-a');
var hash = c + '-' + q;
var question = h('p.cp-faq-questions-q#' + hash);
$(question).click(function () {
if ($(answer).is(':visible')) {
$(question).toggleClass('cp-active-faq');
return void $(answer).slideUp();
}
$(question).toggleClass('cp-active-faq');
$(answer).slideDown();
var t = $(window).scrollTop();
window.location.hash = hash;
$(window).scrollTop(t);
});
questions.push(h('div.cp-faq-questions-items', [
Pages.setHTML(question, item.q),
Pages.setHTML(answer, item.a)
]));
});
categories.push(h('div.cp-faq-category', [
h('h3', faq[c].title),
h('div.cp-faq-category-questions', questions)
]));
});
var hash = window.location.hash;
if (hash) {
$(categories).find(hash).click();
}
return h('div#cp-main', [
Pages.infopageTopbar(),
h('div.container-fluid.cp-faq', [
h('div.container',[
h('center', h('h1', Msg.faq_title)),
]),
]),
h('div.container.cp-faq-ques-det',[
h('div.cp-faq-header.text-center', h('a.nav-item.nav-link', {
href: '/what-is-cryptpad.html'
}, Pages.setHTML(h('h4'),Msg.faq_whatis))),
h('div.cp-faq-container', categories)
]),
Pages.infopageFooter()
]);
};
});

View File

@ -0,0 +1,115 @@
define([
'jquery',
'/common/hyperscript.js',
'/customize/messages.js',
'/customize/application_config.js',
'/common/outer/local-store.js',
'/customize/pages.js'
], function ($, h, Msg, AppConfig, LocalStore, Pages) {
var origin = encodeURIComponent(window.location.hostname);
var accounts = {
donateURL: 'https://accounts.cryptpad.fr/#/donate?on=' + origin,
upgradeURL: 'https://accounts.cryptpad.fr/#/?on=' + origin,
};
return function () {
Msg.features_f_apps_note = AppConfig.availablePadTypes.map(function (app) {
if (AppConfig.registeredOnlyTypes.indexOf(app) !== -1) { return; }
return Msg.type[app];
}).filter(function (x) { return x; }).join(', ');
var premiumButton = h('a', {
href: accounts.upgradeURL,
target: '_blank',
rel: 'noopener noreferrer'
}, h('button.cp-features-register-button', Msg.features_f_subscribe));
$(premiumButton).click(function (e) {
if (LocalStore.isLoggedIn()) { return; }
// Not logged in: go to /login with a redirect to this page
e.preventDefault();
e.stopPropagation();
sessionStorage.redirectTo = '/features.html';
window.location.href = '/login/';
});
return h('div#cp-main', [
Pages.infopageTopbar(),
h('div.container-fluid.cp_cont_features',[
h('div.container',[
h('center', h('h1', Msg.features_title)),
]),
]),
h('div.container',[
h('div.row.cp-container.cp-features-web.justify-content-sm-center',[
h('div.col-12.col-sm-4.cp-anon-user',[
h('div.card',[
h('div.card-body',[
h('h3.text-center',Msg.features_anon)
]),
h('ul.list-group.list-group-flush',
['apps', 'core', 'file0', 'cryptdrive0', 'storage0'].map(function (f) {
return h('li.list-group-item', [
h('div.cp-check'),
h('div.cp-content', [
h('div.cp-feature', Msg['features_f_' + f]),
h('div.cp-note', Msg['features_f_' + f + '_note'])
])
]);
})
),
]),
]),
h('div.col-12.col-sm-4.cp-regis-user',[
h('div.card',[
h('div.card-body',[
h('h3.text-center',Msg.features_registered)
]),
h('ul.list-group.list-group-flush', [
['anon', 'social', 'file1', 'cryptdrive1', 'devices', 'storage1'].map(function (f) {
return h('li.list-group-item', [
h('div.cp-check'),
h('div.cp-content', [
h('div.cp-feature', Msg['features_f_' + f]),
h('div.cp-note', Msg['features_f_' + f + '_note'])
])
]);
}),
]),
h('div.card-body',[
h('div.cp-features-register#cp-features-register', [
h('a', {
href: '/register/'
}, h('button.cp-features-register-button', Msg.features_f_register))
]),
h('div.cp-note', Msg.features_f_register_note)
]),
]),
]),
h('div.col-12.col-sm-4.cp-anon-user',[
h('div.card',[
h('div.card-body',[
h('h3.text-center',Msg.features_premium)
]),
h('ul.list-group.list-group-flush', [
['reg', 'storage2', 'support', 'supporter'].map(function (f) {
return h('li.list-group-item', [
h('div.cp-check'),
h('div.cp-content', [
h('div.cp-feature', Msg['features_f_' + f]),
h('div.cp-note', Msg['features_f_' + f + '_note'])
])
]);
}),
]),
h('div.card-body',[
h('div.cp-features-register#cp-features-subscribe', [
premiumButton
]),
LocalStore.isLoggedIn() ? undefined : h('div.cp-note', Msg.features_f_subscribe_note)
]),
]),
]),
]),
]),
Pages.infopageFooter()
]);
};
});

View File

@ -0,0 +1,148 @@
define([
'jquery',
'/api/config',
'/common/hyperscript.js',
'/customize/messages.js',
'/customize/application_config.js',
'/common/outer/local-store.js',
'/customize/pages.js'
], function ($, Config, h, Msg, AppConfig, LocalStore, Pages) {
var urlArgs = Config.requireConf.urlArgs;
var isAvailableType = function (x) {
if (!Array.isArray(AppConfig.availablePadTypes)) { return true; }
return AppConfig.availablePadTypes.indexOf(x) !== -1;
};
var checkRegisteredType = function (x) {
// Return true if we're registered or if the app is not registeredOnly
if (LocalStore.isLoggedIn()) { return true; }
if (!Array.isArray(AppConfig.registeredOnlyTypes)) { return true; }
return AppConfig.registeredOnlyTypes.indexOf(x) === -1;
};
return function () {
var showingMore = false;
var icons = [
[ 'pad', Msg.main_richTextPad],
[ 'code', Msg.main_codePad],
[ 'slide', Msg.main_slidePad],
[ 'poll', Msg.main_pollPad],
[ 'kanban', Msg.main_kanbanPad],
[ 'whiteboard', Msg.main_whiteboardPad],
[ 'drive', LocalStore.isLoggedIn() ? Msg.main_yourCryptDrive : Msg.main_localPads]
].filter(function (x) {
return isAvailableType(x[0]) && checkRegisteredType(x[0]);
})
.map(function (x, i) {
var s = 'div.bs-callout.cp-callout-' + x[0];
if (i > 2) { s += '.cp-more.cp-hidden'; }
var icon = AppConfig.applicationsIcon[x[0]];
var font = icon.indexOf('cptools') === 0 ? 'cptools' : 'fa';
return h('a', [
{ href: '/'+ x[0] +'/' },
h(s, [
h('i.' + font + '.' + icon),
h('div.pad-button-text', [ h('h4', x[1]) ])
])
]);
});
var more = icons.length < 4? undefined: h('div.bs-callout.cp-callout-more', [
h('div.cp-callout-more-lessmsg.cp-hidden', [
"see less ",
h('i.fa.fa-caret-up')
]),
h('div.cp-callout-more-moremsg', [
"see more ",
h('i.fa.fa-caret-down')
]),
{
onclick: function () {
if (showingMore) {
$('.cp-more, .cp-callout-more-lessmsg').addClass('cp-hidden');
$('.cp-callout-more-moremsg').removeClass('cp-hidden');
} else {
$('.cp-more, .cp-callout-more-lessmsg').removeClass('cp-hidden');
$('.cp-callout-more-moremsg').addClass('cp-hidden');
}
showingMore = !showingMore;
}
}
]);
var _link = h('a', {
href: "https://opencollective.com/cryptpad/contribute",
target: '_blank',
rel: 'noopener',
});
var crowdFunding = AppConfig.disableCrowdfundingMessages ? undefined : h('button', [
Msg.crowdfunding_button
]);
$(crowdFunding).click(function () {
_link.click();
});
var blocks = h('div.container',[
h('div.row.justify-content-sm-center',[
h('div.col-12.col-sm-4.cp-index-block.cp-index-block-host', h('div', [
Pages.setHTML(h('span'), Msg.home_host),
h('div.cp-img-container', [
h('img.agpl', {
src: "/customize/images/AGPL.png",
title: Msg.home_host_agpl
}),
h('a.img', {
href: 'https://blog.cryptpad.fr/2018/11/13/CryptPad-receives-NGI-Startup-Award/',
target: '_blank'
}, h('img.ngi', {
src: "/customize/images/ngi.png",
title: Msg.home_ngi
}))
])
])),
h('div.col-12.col-sm-4.cp-index-block.cp-index-block-product', h('div', [
Msg.home_product
])),
h('div.col-12.col-sm-4.cp-index-block.cp-index-block-help', h('div', [
Msg.crowdfunding_home1,
h('br'),
Msg.crowdfunding_home2,
h('br'),
crowdFunding,
_link
])),
])
]);
return [
h('div#cp-main', [
Pages.infopageTopbar(),
h('div.container.cp-container', [
h('div.row', [
h('div.cp-title.col-12.col-sm-6', [
h('img', { src: '/customize/cryptpad-new-logo-colors-logoonly.png?' + urlArgs }),
h('h1', 'CryptPad'),
h('p', Msg.main_catch_phrase)
]),
h('div.col-12.col-sm-6', [
icons,
more
])
]),
blocks,
/*h('div.row', [
h('div.cp-crowdfunding', [
crowdFunding
])
])*/
]),
]),
Pages.infopageFooter(),
];
};
});

View File

@ -0,0 +1,42 @@
define([
'/common/hyperscript.js',
'/common/common-interface.js',
'/customize/messages.js',
'/customize/pages.js'
], function (h, UI, Msg, Pages) {
return function () {
return [h('div#cp-main', [
Pages.infopageTopbar(),
h('div.container.cp-container', [
h('div.row.align-items-center', [
h('div#data.hidden.col-md-6', Pages.setHTML(h('p.left'), Msg.main_info)),
h('div#userForm.form-group.hidden.col-md-6', [
h('input.form-control#name', {
name: 'name',
type: 'text',
autocomplete: 'off',
autocorrect: 'off',
autocapitalize: 'off',
spellcheck: false,
placeholder: Msg.login_username,
autofocus: true,
}),
h('input.form-control#password', {
type: 'password',
'name': 'password',
placeholder: Msg.login_password,
}),
h('div.checkbox-container', [
UI.createCheckbox('import-recent', Msg.register_importRecent),
]),
h('div.extra', [
h('button.login.first.btn', Msg.login_login)
])
])
]),
]),
Pages.infopageFooter(),
])];
};
});

View File

@ -0,0 +1,46 @@
define([
'/common/hyperscript.js',
'/customize/messages.js',
'/customize/pages.js'
], function (h, Msg, Pages) {
return function () {
return h('div#cp-main', [
Pages.infopageTopbar(),
h('.container-fluid.cp-privacy-top', [
h('div.container',[
h('center', h('h1', Msg.policy_title)),
]),
]),
h('div.container.cp-container.cp-privacy',[
h('h3', Msg.policy_whatweknow),
h('hr'),
Pages.setHTML(h('p'), Msg.policy_whatweknow_p1),
h('h3', Msg.policy_howweuse),
h('hr'),
h('p', Msg.policy_howweuse_p1),
h('p', Msg.policy_howweuse_p2),
h('h3', Msg.policy_whatwetell),
h('hr'),
h('p', Msg.policy_whatwetell_p1),
h('h3', Msg.policy_links),
h('hr'),
h('p', Msg.policy_links_p1),
h('h3', Msg.policy_ads),
h('hr'),
h('p', Msg.policy_ads_p1),
h('h3', Msg.policy_choices),
h('hr'),
h('p', Msg.policy_choices_open),
Pages.setHTML(h('p'), Msg.policy_choices_vpn),
]),
Pages.infopageFooter()
]);
};
});

View File

@ -0,0 +1,69 @@
define([
'jquery',
'/common/hyperscript.js',
'/common/common-interface.js',
'/customize/messages.js',
'/customize/pages.js'
], function ($, h, UI, Msg, Pages) {
return function () {
return [h('div#cp-main', [
Pages.infopageTopbar(),
h('div.container-fluid.cp-register-wel',[
h('div.container',[
h('div.row',[
h('div.col-12',[
h('h1.text-center', Msg.register_header)
])
])
])
]),
h('div.container.cp-container', [
h('div.row.cp-register-det', [
h('div#data.hidden.col-md-6', [
Pages.setHTML(h('p.register-explanation'), Msg.register_explanation)
]),
h('div#userForm.form-group.hidden.col-md-6', [
h('a', {
href: '/features.html'
}, Msg.register_whyRegister),
h('input.form-control#username', {
type: 'text',
autocomplete: 'off',
autocorrect: 'off',
autocapitalize: 'off',
spellcheck: false,
placeholder: Msg.login_username,
autofocus: true,
}),
h('input.form-control#password', {
type: 'password',
placeholder: Msg.login_password,
}),
h('input.form-control#password-confirm', {
type: 'password',
placeholder: Msg.login_confirm,
}),
h('div.checkbox-container', [
UI.createCheckbox('import-recent', Msg.register_importRecent, true)
]),
h('div.checkbox-container', [
$(UI.createCheckbox('accept-terms')).find('.cp-checkmark-label').append(Msg.register_acceptTerms).parent()[0]
]),
h('button#register.btn.cp-login-register', Msg.login_register)
])
]),
h('div.row.cp-register-test',[
h('hr'),
h('div.col-12', [
Pages.setHTML(h('p.test-details'), " \"Tools like Etherpad and Google Docs [...] all share a weakness, which is that whomever owns the document server can see everything you're typing. Cryptpad is a free/open project that uses some of the ideas behind blockchain to implement a \"zero-knowledge\" version of a collaborative document editor, ensuring that only the people working on a document can see it.\" "),
h('a.cp-test-source.pull-right', { href : 'http://boingboing.net/2016/09/26/cryptpad-a-freeopen-end-to.html'}, "Cory Doctorow")
])
])
]),
Pages.infopageFooter(),
])];
};
});

View File

@ -0,0 +1,21 @@
define([
'/common/hyperscript.js',
'/customize/messages.js',
'/customize/pages.js'
], function (h, Msg, Pages) {
return function () {
return h('div#cp-main', [
Pages.infopageTopbar(),
h('div.container.cp-container', [
h('center', h('h1', Msg.tos_title)),
h('p', Msg.tos_legal),
h('p', Msg.tos_availability),
h('p', Msg.tos_e2ee),
h('p', Msg.tos_logs),
h('p', Msg.tos_3rdparties),
]),
Pages.infopageFooter()
]);
};
});

View File

@ -0,0 +1,64 @@
define([
'/api/config',
'/common/hyperscript.js',
'/customize/messages.js',
'/customize/pages.js'
], function (Config, h, Msg, Pages) {
var urlArgs = Config.requireConf.urlArgs;
return function () {
return h('div#cp-main', [
Pages.infopageTopbar(),
h('div.container-fluid.cp-what-is',[
h('div.container',[
h('div.row',[
h('div.col-12.text-center', h('h1', Msg.whatis_title)),
]),
]),
]),
h('div.container.cp-container', [
h('div.row.align-items-center', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6', [
Pages.setHTML(h('h2'), Msg.whatis_collaboration),
Pages.setHTML(h('p'), Msg.whatis_collaboration_p1),
Pages.setHTML(h('p'), Msg.whatis_collaboration_p2),
Pages.setHTML(h('p'), Msg.whatis_collaboration_p3),
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6', [
h('img', { src: '/customize/images/pad_screenshot.png?' + urlArgs }),
]),
]),
h('div.row.align-items-center', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6.order-2', [
Pages.setHTML(h('h2'), Msg.whatis_zeroknowledge),
Pages.setHTML(h('p'), Msg.whatis_zeroknowledge_p1),
Pages.setHTML(h('p'), Msg.whatis_zeroknowledge_p2),
Pages.setHTML(h('p'), Msg.whatis_zeroknowledge_p3),
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6.order-1', [
h('img#zeroknowledge', { src: '/customize/images/zeroknowledge_small.png?' + urlArgs }),
]),
]),
h('div.row.align-items-center', [
h('div.col-12.col-sm-12.col-md-12.col-lg-6', [
Pages.setHTML(h('h2'), Msg.whatis_drive),
Pages.setHTML(h('p'), Msg.whatis_drive_p1),
Pages.setHTML(h('p'), Msg.whatis_drive_p2),
Pages.setHTML(h('p'), Msg.whatis_drive_p3),
]),
h('div.col-12.col-sm-12.col-md-12.col-lg-6', [
h('img', { src: '/customize/images/drive_screenshot.png?' + urlArgs }),
]),
]),
h('div.row.align-items-center', [
h('div.col-12', [
Pages.setHTML(h('h2.text-center'), Msg.whatis_business),
Pages.setHTML(h('p'), Msg.whatis_business_p1),
Pages.setHTML(h('p'), Msg.whatis_business_p2),
]),
]),
]),
Pages.infopageFooter(),
]);
};
});

View File

@ -46,6 +46,38 @@
display: block;
}
}
// Code app
body.cp-app-code {
display: block;
* {
visibility: hidden;
height: auto;
max-height: none;
}
#cme_toolbox {
display: none;
}
#cp-app-code-editor {
display: block;
#cp-app-code-container {
display: none;
}
#cp-app-code-preview {
display: block;
#cp-app-code-print {
display: block;
overflow: visible !important;
width: 100%;
visibility: visible;
* { visibility: visible; }
pre { border: none; }
}
#cp-app-code-preview-content {
display: none !important;
}
}
}
}
}
}
}

View File

@ -43,6 +43,10 @@
//transform: scale(0.1);
//transform: scale(1);
h1, h2, h3 {
font-size: 1.5em;
}
.cp-corner-filler {
float: left;
clear: left;
@ -94,6 +98,8 @@
.cp-corner-footer {
font-style: italic;
font-size: 0.8em;
}
.cp-corner-footer, .cp-corner-text {
a {
color: @corner-link;
&:hover {
@ -103,10 +109,11 @@
}
button {
color: white;
border: 0px;
padding: 5px;
color: @colortheme_base;
margin-left: 5px;
outline: none;
&.cp-corner-primary {
background-color: @corner-button-ok;
font-weight: bold;

View File

@ -0,0 +1,34 @@
.cursor_main() {
// CodeMirror
.cp-codemirror-cursor {
cursor: default;
background-color: red;
background-clip: padding-box;
padding: 0 1px;
border: 2px solid red;
border-right-color: transparent !important;
border-left-color: transparent !important;
}
.cp-codemirror-selection {
background-color: rgba(255,0,0,0.3);
}
// Tippy
.cp-cursor-avatar {
@size: 32px;
display: flex;
align-items: center;
media-tag {
min-height: @size;
max-height: @size;
min-width: @size;
max-width: @size;
margin-right: 10px;
img {
border-radius: 4px;
max-height: 100%;
max-width: 100%;
}
}
}
}

View File

@ -64,7 +64,7 @@
&:not(.fa) {
font: @dropdown_font;
}
&.fa {
&.fa, &.cptools {
font-size: 18px;
&::before {
width: 40px;
@ -76,7 +76,7 @@
}
}
.fa {
.fa, .cptools {
width: 20px;
text-align: center;
margin-right: 5px !important;

View File

@ -21,9 +21,11 @@
tr:nth-child(1) {
background-color: darken(@colortheme_modal-bg, 20%);
td {
text-align: center;
font-weight: bold;
padding: 0.25em;
&:nth-child(4), &:nth-child(5) {
text-align: center;
}
}
}
@upload_pad_h: 0.25em;
@ -38,7 +40,7 @@
}
}
.cp-fileupload-table-progress {
width: 200px;
width: 25%;
position: relative;
text-align: center;
box-sizing: border-box;

View File

@ -12,6 +12,8 @@
@import (reference) './font.less';
@import (reference) "./app-print.less";
@import (reference) "./app-noscroll.less";
@import (reference) "./messenger.less";
@import (reference) "./cursor.less";
.framework_main(@bg-color, @warn-color, @color) {
--LessLoader_require: LessLoader_currentFile();
@ -36,6 +38,8 @@
.tippy_main();
.checkmark_main(20px);
.password_main();
.messenger_main();
.cursor_main();
.creation_main(
@bg-color: @bg-color,
@color: @color

View File

@ -38,7 +38,7 @@
color: @help-text-color;
color: var(--help-text-color);
margin: 0;
padding: 15px;
padding: 5px 15px;
a {
color: @help-link-color;
color: var(--help-link-color);
@ -52,7 +52,13 @@
h3 {
font-size: 16px;
}
ul, ol, p { margin: 0; }
ul, ol, p, h1, h2, h3 { margin: 0; }
&.cp-help-small {
ul {
display: none;
}
cursor: pointer;
}
}
}
}

View File

@ -28,7 +28,7 @@
background-color: rgba(0,0,0,0.2);
color: #666;
}
.fa {
.fa, .cptools {
display: block;
font-size: 64px;
margin: 18px 0;

View File

@ -11,7 +11,7 @@
cursor: pointer;
height: @variables_bar-height;
line-height: @variables_bar-height - 10px;
.fa {
.fa, .cptools {
width: 25px;
}
&:hover {

View File

@ -28,9 +28,12 @@
border-collapse: collapse;
tr {
th {
border: 3px solid @color;
border: 1px solid @color;
padding: 15px;
}
td {
border: 1px solid @color;
}
}
}
}

View File

@ -0,0 +1,382 @@
@import (reference) './avatar.less';
@import (reference) "./colortheme-all.less";
.messenger_main() {
--LessLoader_require: LessLoader_currentFile();
};
& {
@keyframes example {
0% {
background: rgba(0,0,0,0.1);
}
50% {
background: rgba(0,0,0,0.3);
}
100% {
background: rgba(0,0,0,0.1);
}
}
@button-border: 2px;
@bg-color: @colortheme_friends-bg;
@color: @colortheme_friends-color;
@room-height: 48px;
#cp-app-contacts-container {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
min-height: 0;
&.ready {
background-size: cover;
background-position: center;
}
}
.cp-app-contacts-spinner {
display: none;
}
.cp-app-contacts-initializing {
.cp-app-contacts-spinner {
color: white;
display: block;
}
.cp-app-contacts-info {
display: none;
}
#cp-app-contacts-friendlist,
#cp-app-contacts-messaging {
display: flex;
justify-content: center;
align-items: center;
}
}
#cp-app-contacts-friendlist {
width: 200px;
height: 100%;
background-color: lighten(@bg-color, 10%);
overflow-y: auto;
display: flex;
flex-flow: column;
.cp-app-contacts-friend {
background: rgba(0,0,0,0.1);
padding: 5px;
margin: 10px;
margin-bottom: 0;
cursor: pointer;
position: relative;
height: @room-height;
.cp-app-contacts-right-col {
margin-left: 5px;
display: flex;
flex-flow: column;
flex: 1;
min-width: 0;
.cp-app-contacts-name {
white-space: nowrap;
}
}
&:hover {
background-color: rgba(0,0,0,0.3);
}
&.cp-app-contacts-notify {
animation: example 2s ease-in-out infinite;
}
}
.cp-app-contacts-remove {
cursor: pointer;
width: 20px;
&:hover {
color: darken(@color, 20%);
}
}
.cp-app-contacts-category {
display: flex;
flex-flow: column;
flex-grow: 0;
flex-shrink: 0;
.cp-app-contacts-category-title {
order: 1;
font-size: 18px;
margin: 0px 5px;
text-align: center;
background: rgba(0,0,0,0.1);
font-weight: bold;
height: 22px;
line-height: 22px;
}
.cp-app-contacts-category-content {
order: 2;
display: flex;
flex-flow: column-reverse;
padding-bottom: 10px;
&:empty {
display: none;
& ~ .cp-app-contacts-category-title {
display: none;
}
}
}
}
}
#cp-app-contacts-container.cp-app-contacts-inapp {
#cp-app-contacts-friendlist {
display: none;
/*
transition: width 0.2s ease-in-out 0.2s;
width: 68px;
.cp-app-contacts-friend {
.cp-app-contacts-right-col {
overflow: hidden;
}
}
.cp-app-contacts-category-title {
transition: font-size 0.2s ease-in-out 0.2s;
margin: 0px 2px;
font-size: 16px;
}
&:hover {
transition-delay: 1.5s;
width: 200px !important;
.cp-app-contacts-category-title {
transition-delay: 1.5s;
font-size: 18px;
}
}
*/
}
}
#cp-app-contacts-friendlist .cp-app-contacts-friend, #cp-app-contacts-messaging .cp-avatar {
.avatar_main(30px);
&.cp-avatar {
display: flex;
}
cursor: pointer;
color: @color;
media-tag {
img {
color: #000;
}
}
media-tag, .cp-avatar-default {
//margin-right: 5px;
flex-shrink: 0;
z-index: 1;
margin: 4px;
}
.cp-app-contacts-status {
//width: 5px;
display: inline-block;
position: absolute;
//right: 0;
//top: 0;
//bottom: 0;
//opacity: 0.7;
//background-color: #777;
/* width: (@room-height - 6px);
top: 3px;
bottom: 3px;
left: 3px;
border-radius: 100%;
*/
width: 10px;
height: 10px;
top: 0;
right: 0;
border-bottom-left-radius: 100%;
&.cp-app-contacts-online {
//background-color: green;
//background-color: white;
background-color: #c5ffa8;
}
&.cp-app-contacts-offline {
display: none;
//background-color: red;
}
}
}
.placeholder (@color: #bbb) {
&::-webkit-input-placeholder { /* WebKit, Blink, Edge */
color: @color;
}
&:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
color: @color;
opacity: 1;
}
&::-moz-placeholder { /* Mozilla Firefox 19+ */
color: @color;
opacity: 1;
}
&:-ms-input-placeholder { /* Internet Explorer 10-11 */
color: @color;
}
&::-ms-input-placeholder { /* Microsoft Edge */
color: @color;
}
}
#cp-app-contacts-messaging {
flex: 1;
height: 100%;
background-color: lighten(@bg-color, 20%);
min-width: 0;
.cp-app-contacts-info {
padding: 20px;
}
.cp-app-contacts-header {
background-color: lighten(@bg-color, 15%);
padding: 0;
display: flex;
justify-content: space-between;
align-items: center;
height: 50px;
.hover () {
height: 100%;
line-height: 30px;
padding: 10px;
&:hover {
background-color: rgba(50,50,50,0.3);
}
}
.cp-avatar,
.cp-app-contacts-right-col {
flex: 1 1 auto;
}
.cp-app-contacts-remove-history {
.hover;
}
.cp-avatar {
margin: 10px;
}
.cp-app-contacts-more-history {
//display: none;
.hover;
&.cp-app-contacts-faded {
color: darken(@bg-color, 5%);
}
}
.cp-app-contacts-header-title {
padding: 10px;
flex: 1;
}
}
.cp-app-contacts-tips {
margin: 1em;
background-color: lighten(@bg-color, 15%);
font-size: 14px;
padding: 10px;
position: relative;
.cp-app-contacts-tips-close {
cursor: pointer;
position: absolute;
top: 2px;
right: 2px;
}
}
.cp-app-contacts-chat {
height: 100%;
display: flex;
flex-flow: column;
.cp-app-contacts-messages {
padding: 0 20px;
margin: 10px 0;
flex: 1;
overflow-x: auto;
.cp-app-contacts-message {
display: flex;
flex-wrap: wrap;
& > div {
padding: 0 10px;
}
.cp-app-contacts-content {
overflow: hidden;
word-wrap: break-word;
&> * {
margin: 0;
}
flex: 1;
min-width: 70%;
position: relative;
}
.cp-app-contacts-date {
display: none;
font-style: italic;
}
.cp-app-contacts-sender {
margin-top: 10px;
font-weight: bold;
background-color: rgba(0,0,0,0.1);
display: flex;
justify-content: space-between;
width: 100%;
}
.cp-app-contacts-time {
display: none;
font-size: 0.8em;
align-items: center;
color: @color;
font-weight: bold;
position: absolute;
right: 0;
top: 0;
bottom: 0;
background: rgba(0,0,0,0.3);
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
padding: 0 10px;
}
&:hover {
.cp-app-contacts-time {
display: flex;
}
}
}
}
}
.cp-app-contacts-input {
background-color: lighten(@bg-color, 15%);
height: auto;
min-height: 50px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 5%;
textarea {
margin: 5px 0;
padding: 5px 10px;
border: none;
height: 54px; // 2 lines (22px height) + 2 margins (5px)
flex: 1;
background-color: darken(@bg-color, 10%);
color: @color;
resize: none;
overflow-y: auto;
.placeholder(#bbb);
&[disabled="true"] {
.placeholder(#999);
}
}
button {
height: 54px;
border-radius: 0;
border: none;
background-color: darken(@bg-color, 15%);
&:hover {
background-color: darken(@bg-color, 20%);
}
}
}
}
}

View File

@ -72,6 +72,18 @@
.modal_main();
};
& {
@keyframes notification {
0% {
background: rgba(0,0,0,0);
}
50% {
background: rgba(0,0,0,0.2);
}
100% {
background: rgba(0,0,0,0);
}
}
.toolbar_vars();
@toolbar_line-height: 32px;
@toolbar_top-height: 64px;
@ -134,9 +146,39 @@
}
}
.cp-toolbar-userlist-drawer {
.cp-toolbar-chat-drawer {
background-color: @toolbar-bg-color;
background-color: var(--toolbar-bg-color);
font: @colortheme_app-font-size @colortheme_font;
width: 20%;
min-width: 200px;
display: block;
overflow-y: auto;
overflow-x: hidden;
padding: 0;
box-sizing: border-box;
position: relative;
order: -2;
resize: horizontal;
#cp-app-contacts-container {
height: 100%;
}
.cp-toolbar-chat-drawer-close {
color: @toolbar-color;
color: var(--toolbar-color);
position: absolute;
top: 0;
right: 1px;
font-size: 15px;
opacity: 0.5;
cursor: pointer;
text-shadow: unset;
&:hover {
opacity: 1;
}
}
}
.cp-toolbar-userlist-drawer {
font: @colortheme_app-font-size @colortheme_font;
min-width: 175px;
width: 175px;
@ -145,6 +187,7 @@
overflow-x: hidden;
padding: 10px;
box-sizing: border-box;
order: -3;
.cp-toolbar-userlist-drawer-close {
position: absolute;
margin-top: -10px;
@ -192,6 +235,7 @@
padding: 5px;
margin: 2px 0;
background: rgba(0,0,0,0.1);
border-right: 3px solid transparent;
.avatar_main(30px);
.cp-avatar-default, media-tag {
margin-right: 5px;
@ -219,6 +263,14 @@
display: flex;
justify-content: space-between;
align-items: center;
button {
width: 20px;
font-size: 16px;
padding: 0;
border: none;
height: 20px;
cursor: pointer;
}
}
.cp-toolbar-userlist-name-input {
flex: 1;
@ -235,14 +287,6 @@
min-height: 0;
text-overflow: ellipsis;
}
.cp-toolbar-userlist-name-edit {
width: 20px;
font-size: 16px;
padding: 0;
border: none;
height: 20px;
cursor: pointer;
}
.cp-toolbar-userlist-friend {
padding: 0;
}
@ -276,11 +320,15 @@
margin: 50px;
}
&> div {
flex: 1;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: center;
overflow-y: auto;
}
&> div:last-child {
flex: unset;
margin: 50px 0;
}
}
@ -299,13 +347,15 @@
margin-left: 5px;
}
@media screen and (max-height: @browser_media-not-big) {
@media screen and (max-height: @browser_media-medium-screen),
screen and (max-width: @browser_media-medium-screen) {
.cp-modal {
& > p {
display: none;
}
& > div {
align-content: unset;
align-items: center;
li {
height: 40px;
width: 200px;
@ -313,9 +363,11 @@
align-items: center;
.fa {
font-size: 32px;
min-width: 50px;
}
.cp-icons-name {
height: auto;
text-align: left;
}
}
}
@ -344,7 +396,7 @@
color: @toolbar-color;
color: var(--toolbar-color);
}
.cp-toolbar-userlist-name-edit {
.cp-toolbar-userlist-button {
color: @toolbar-userlist-name-edit;
color: var(--toolbar-userlist-name-edit);
background: transparent;
@ -902,6 +954,9 @@
width: 100%;
cursor: default;
font-size: 32px;
display: inline-flex;
justify-content: center;
align-items: center;
}
&.cp-avatar {
.avatar_main(48px);
@ -961,7 +1016,8 @@
height: @toolbar_line-height;
}
#cp-toolbar-userlist-drawer-open { order: 1; }
#cp-toolbar-userlist-drawer-open { order: 0; }
#cp-toolbar-chat-drawer-open { order: 1; }
.cp-toolbar-share-button { order: 2; }
.cp-toolbar-spinner { order: 3; }
@ -969,6 +1025,11 @@
width: 125px;
text-align: center;
}
#cp-toolbar-chat-drawer-open button {
&.cp-toolbar-notification {
animation: notification 2s ease-in-out infinite;
}
}
.cp-toolbar-share-button {
width: 50px;
text-align: center;

View File

@ -19,7 +19,7 @@
color: #fff;
}
}
#cp-features-register {
.cp-features-register {
text-align: center;
padding: 20px;
}
@ -39,24 +39,51 @@
.card {
box-shadow: 0 5px 15px rgba(69, 145, 196, 0.3);
border: none;
.card-body {
display: flex;
justify-content: center;
align-items: center;
flex-flow: column;
h3 {
margin: 0;
}
}
}
h3 {
color: #fff;
}
.list-group {
li {
&:before {
content: "\f00c";
font-family: "FontAwesome";
font-size: 14px;
color: @cryptpad_color_blue;
padding-right: 10px;
}
display: flex;
padding-left: 0;
padding-right: 5px;
}
div {
display: inline;
&.cp-check {
width: 30px;
display: flex;
align-items: center;
justify-content: center;
&:before {
content: "\f00c";
font-family: "FontAwesome";
font-size: 14px;
color: @cryptpad_color_blue;
}
}
&.cp-content {
flex: 1;
display: flex;
flex-flow: column;
}
&.cp-feature {
font-weight: bold;
}
}
}
div.cp-note {
font-size: 0.8em;
}
a.voted {
opacity: 0.6;
margin-left: 15px;
@ -70,7 +97,9 @@
}
.cp-anon-user {
.card-body {
background-color: @cryptpad_color_blue;
&:first-of-type {
background-color: @cryptpad_color_blue;
}
}
}
.cp-regis-user {

View File

@ -21,6 +21,13 @@
margin-top: 6em;
}
}
& > .cp-container {
flex: 1;
display: flex;
flex-flow: column;
justify-content: space-around;
justify-content: space-evenly;
}
}
body {
font-family: "Open Sans", Helvetica;
@ -142,22 +149,24 @@
.bs-callout:hover.cp-callout-more {
transform: none !important;
}
.bs-callout .fa {
display: flex;
align-items: center;
font-size: 2em;
padding-left: 0.57em;
width: 2em;
transition: width 0.1s;
color: #fff;
.bs-callout {
.fa, .cptools {
display: flex;
align-items: center;
font-size: 2.5em;
justify-content: center;
width: 1.3em;
transition: width 0.1s;
color: #fff;
}
}
.cp-callout-pad .fa { background-color: @colortheme_pad-bg; }
.cp-callout-code .fa { background-color: @colortheme_code-bg; }
.cp-callout-slide .fa { background-color: @colortheme_slide-bg; }
.cp-callout-poll .fa { background-color: @colortheme_poll-bg; }
.cp-callout-kanban .fa { background-color: @colortheme_kanban-bg; }
.cp-callout-whiteboard .fa { background-color: @colortheme_whiteboard-bg; }
.cp-callout-recent .fa { background-color: @colortheme_drive-bg; }
.cp-callout-pad .cptools { background-color: @colortheme_pad-bg; }
.cp-callout-code .cptools { background-color: @colortheme_code-bg; }
.cp-callout-slide .cptools { background-color: @colortheme_slide-bg; }
.cp-callout-poll .cptools { background-color: @colortheme_poll-bg; }
.cp-callout-kanban .cptools { background-color: @colortheme_kanban-bg; }
.cp-callout-whiteboard .cptools { background-color: @colortheme_whiteboard-bg; }
.cp-callout-drive .fa { background-color: @colortheme_drive-bg; }
.cp-hidden { display: none !important; }
.cp-callout-more {
display: inline-block;
@ -172,7 +181,7 @@
div {
.infopages_link();
color: #fff;
.fa {
.fa, .cptools {
font-size: inherit;
padding: 0;
width: 1em;
@ -180,6 +189,48 @@
}
}
}
.cp-index-block-help {
button {
outline: none;
background-color: @colortheme_logo-2;
color: @colortheme_base;
border: none;
padding: 10px 20px;
border-radius: 44px;
cursor: pointer;
&:hover {
background-color: lighten(@colortheme_logo-2, 3%);
}
}
}
.cp-index-block {
min-height: 100%;
& > div {
background: rgba(0,0,0,0.5);
margin: 0 5px;
padding: 15px 10px;
height: 100%;
display: flex;
flex-flow: column;
justify-content: space-evenly;
}
.cp-img-container {
display: flex;
}
img, a.img {
margin: auto;
background: white;
&.agpl {
max-height: 50px;
}
&.ngi {
max-height: 100px;
}
}
}
@media (min-width: 576px) and (max-width: 767px) {
.container {
padding-left: 0;

View File

@ -2,51 +2,66 @@ define([
'jquery',
'/common/hyperscript.js',
'/customize/pages.js',
'/bower_components/nthen/index.js',
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
], function ($, h, Pages) {
], function ($, h, Pages, nThen) {
$(function () {
var $body = $('body');
var infoPage = function () {
return h('div#mainBlock.hidden', typeof(Pages[location.pathname]) === 'function'?
Pages[location.pathname](): [h('div#container')]);
};
var $main = $(infoPage());
var pathname = location.pathname;
// add class on info-pages
var css = location.pathname.replace(/(index)?\.html$/gi, "") // .html
var pageName = pathname.replace(/(index)?\.html$/gi, "") // .html
.replace(/[^a-zA-Z]+/gi, '-') // any non-alpha character
.replace(/^-|-$/g, ''); // starting/trailing dashes
if (css === '') { css = 'index'; }
$('body').addClass('cp-page-' + css);
if (pageName === '') { pageName = 'index'; }
$('body').addClass('cp-page-' + pageName);
var infoPage = function () {
return h('div#mainBlock.hidden', typeof(Pages[pathname]) === 'function'?
Pages[pathname](): [h('div#container')]);
};
window.Tether = function () {};
require([
'less!/customize/src/less2/pages/page-' + css + '.less',
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css'
], function () {
$body.append($main);
if (/^\/user\//.test(pathname)) {
require([ '/user/main.js'], function () {});
} else if (/^\/register\//.test(pathname)) {
require([ '/register/main.js' ], function () {});
} else if (/^\/login\//.test(pathname)) {
require([ '/login/main.js' ], function () {});
} else if (/^\/($|^\/index\.html$)/.test(pathname)) {
// TODO use different top bar
require([ '/customize/main.js', ], function () {});
} else if (/invite/.test(pathname)) {
require([ '/invite/main.js'], function () {});
} else if (/faq/.test(pathname)) {
window.location.hash = window.location.hash;
} else {
require([ '/customize/main.js', ], function () {});
}
nThen(function (waitFor) {
var w = waitFor();
require([
'/customize/pages/' + pageName + '.js',
], function (Page) {
infoPage = Page;
w();
}, function () {
w();
});
}).nThen(function () {
require([
'less!/customize/src/less2/pages/page-' + pageName + '.less',
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
'css!/customize/fonts/cptools/style.css'
], function () {
var $main = $(infoPage());
$body.append($main);
if (/^\/register\//.test(pathname)) {
require([ '/register/main.js' ], function () {});
} else if (/^\/login\//.test(pathname)) {
require([ '/login/main.js' ], function () {});
} else if (/^\/($|^\/index\.html$)/.test(pathname)) {
// TODO use different top bar
require([ '/customize/main.js', ], function () {});
} else if (/invite/.test(pathname)) {
require([ '/invite/main.js'], function () {});
} else if (/faq/.test(pathname)) {
var hash = window.location.hash;
window.location.hash = '';
window.location.hash = hash;
} else {
require([ '/customize/main.js', ], function () {});
}
});
});
});
});

View File

@ -6,11 +6,11 @@ If you don't have Cryptpad installed locally, start by following the steps in th
## Getting started
Once everything is working, copy the default (English) source file (`/customize.dist/translations/messages.js`) to a file named according to your language's [ISO 639-1 Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), like `/customize.dist/translations/messages.fr.js`.
Once everything is working, copy the default (English) source file (`/www/common/translations/messages.js`) to a file named according to your language's [ISO 639-1 Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), like `/www/common/translations/messages.fr.js`.
There is no ISO 639-1 language code for _English-pirate_, so we'll just call it `messages.pirate.js`.
```Bash
cd /customize.dist/translations/
cd www/common/translations/
cp messages.js messages.pirate.js
```
@ -21,21 +21,17 @@ There are comments indicating what to modify in three places:
```javascript
(function () {
var LS_LANG = "CRYPTPAD_LANG";
var getStoredLanguage = function () { return localStorage.getItem(LS_LANG); };
var getBrowserLanguage = function () { return navigator.language || navigator.userLanguage; };
var getLanguage = function () { return getStoredLanguage() || getBrowserLanguage(); };
var language = getLanguage();
// add your module to this map so it gets used
// please use the translated name of your language ("Français" and not "French"
// please use the translated name of your language ("Français" and not "French")
var map = {
'fr': 'Français',
'es': 'Español',
'pl': 'Polski',
'de': 'Deutsch',
'pt-br': 'Português do Brasil'
'pt-br': 'Português do Brasil',
'ro': 'Română',
'zh': '繁體中文',
'el': 'Ελληνικά',
};
```
@ -43,31 +39,45 @@ We need to modify that map to include our translation:
```javascript
(function () {
var LS_LANG = "CRYPTPAD_LANG";
var getStoredLanguage = function () { return localStorage.getItem(LS_LANG); };
var getBrowserLanguage = function () { return navigator.language || navigator.userLanguage; };
var getLanguage = function () { return getStoredLanguage() || getBrowserLanguage(); };
var language = getLanguage();
// add your module to this map so it gets used
// please use the translated name of your language ("Français" and not "French"
// please use the translated name of your language ("Français" and not "French")
var map = {
'fr': 'Français',
'es': 'Español',
'pl': 'Polski',
'de': 'Deutsch',
'pt-br': 'Português do Brasil'
'pt-br': 'Português do Brasil',
'ro': 'Română',
'zh': '繁體中文',
'el': 'Ελληνικά',
'pirate': 'English Pirate', // add our module to the map of languages
};
```
Just add your module in a similar fashion to the existing translations, save your changes, and close `/customize.dist/messages.js`.
You also need to add a customizable version of you translation. To do so, make a copy of the file `/customize.dist/translations/messages.js` with your translation name (`messages.pirate.js` in our case), and change its content to load the correct language file:
```javascript
/*
* You can override the translation text using this file.
* The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js)
in a 'customize' directory (/customize/translations/messages.{LANG}.js).
* If you want to check all the existing translation keys, you can open the internal language file
but you should not change it directly (/common/translations/messages.{LANG}.js)
*/
define(['/common/translations/messages.pirate.js'], function (Messages) { // Change the file name here
// Replace the existing keys (in your copied file) here:
// Messages.button_newpad = "New Rich Text Document";
return Messages;
});
```
That's all!
## Actually translating content
Now we can go back to our file, `/customize.dist/translations/messages.pirate.js` and start to add our Pirate-language customizations.
Now we can go back to our file, `/www/common/translations/messages.pirate.js` and start to add our Pirate-language customizations.
Open the translation file you created in `/customize.dist/translations/`.
You should see something like:
@ -115,5 +125,5 @@ We're happy to help.
When a key is nolonger used (such as presentSuccess) you can delete it using this bash one-liner.
```shell
( export KEY=presentSuccess && grep -nr "$KEY" ./customize.dist/translations/ | sed 's/:.*$//' | while read x; do sed -i -e "/out\.$KEY =/d" $x; done )
```
( export KEY=presentSuccess && grep -nr "$KEY" ./www/common/translations/ | sed 's/:.*$//' | while read x; do sed -i -e "/out\.$KEY =/d" $x; done )
```

File diff suppressed because it is too large Load Diff

View File

@ -1,778 +1,14 @@
define(function () {
var out = {};
out.main_title = "CryptPad: Zero Knowledge, συνεργατική επεξεργασία σε πραγματικό χρόνο";
out.main_slogan = "Ισχύς εν τη ενώσει - Η συνεργασία είναι η λύση"; // TODO remove?
out.type = {};
out.type.pad = 'Εμπλουτισμένο κείμενο';
out.type.code = 'Κώδικας';
out.type.poll = 'Δημοσκόπηση';
out.type.slide = 'Παρουσίαση';
out.type.drive = 'Αποθηκευτικός χώρος';
out.type.whiteboard = 'Πίνακας σχεδιασμού';
out.type.file = 'Αρχείο';
out.type.media = 'Πολυμέσα';
out.type.todo = "Εργασίες";
out.type.contacts = 'Επαφές';
out.button_newpad = 'Νέο pad εμπλουτισμένου κειμένου';
out.button_newcode = 'Νέο pad κώδικα';
out.button_newpoll = 'Νέα δημοσκόπηση';
out.button_newslide = 'Νέα παρουσίαση';
out.button_newwhiteboard = 'Νέος πίνακας';
// NOTE: We want to update the 'common_connectionLost' key.
// Please do not add a new 'updated_common_connectionLostAndInfo' but change directly the value of 'common_connectionLost'
out.updated_0_common_connectionLost = "<b>Η σύνδεση με τον διακομιστή χάθηκε</b><br>Βρίσκεστε σε λειτουργία ανάγνωσης μόνο μέχρι να επανέλθει η σύνδεση.";
out.common_connectionLost = out.updated_0_common_connectionLost;
out.websocketError = 'Αδυναμία σύνδεσης στον διακομιστή...';
out.typeError = "Αυτό το pad δεν είναι συμβατό με την επιλεγμένη εφαρμογή";
out.onLogout = 'Έχετε αποσυνδεθεί, {0}κάντε "κλικ" εδώ{1} για να συνδεθείτε<br>ή πατήστε <em>Escape</em> για να προσπελάσετε το έγγραφο σε λειτουργία ανάγνωσης μόνο.';
out.wrongApp = "Αδυναμία προβολής του περιεχομένου αυτής της συνεδρίας στον περιηγητή σας. Παρακαλώ δοκιμάστε επαναφόρτωση της σελίδας.";
out.loading = "Φόρτωση...";
out.error = "Σφάλμα";
out.saved = "Αποθηκεύτηκε";
out.synced = "Όλα έχουν αποθηκευτεί";
out.deleted = "Το έγγραφο διαγράφηκε από τον αποθηκευτικό σας χώρο";
out.realtime_unrecoverableError = "Η μηχανή πραγματικού χρόνου αντιμετώπισε κάποιο ανεπανόρθωτο σφάλμα. Πατήστε OK για επαναφόρτωση.";
out.disconnected = 'Έγινε αποσύνδεση';
out.synchronizing = 'Γίνεται συγχρονισμός';
out.reconnecting = 'Γίνεται επανασύνδεση...';
out.typing = "Γίνεται επεξεργασία";
out.initializing = "Γίνεται προετοιμασία...";
out.forgotten = 'Μετακινήθηκε στον κάδο ανακύκλωσης';
out.errorState = 'Κρίσιμο σφάλμα: {0}';
out.lag = 'Αργή σύνδεση';
out.readonly = 'Λειτουργία ανάγνωσης μόνο';
out.anonymous = "Ανώνυμος/η";
out.yourself = "Ο εαυτός σας";
out.anonymousUsers = "Ανώνυμοι συντάκτες";
out.anonymousUser = "Ανώνυμος συντάκτης";
out.users = "Χρήστες";
out.and = "Και";
out.viewer = "Θεατής";
out.viewers = "Θεατές";
out.editor = "Συντάκτης";
out.editors = "Συντάκτες";
out.userlist_offline = "Είσαστε προς το παρόν εκτός σύνδεσης, η λίστα χρηστών δεν είναι διαθέσιμη.";
out.language = "Γλώσσα";
out.comingSoon = "Έρχεται σύντομα...";
out.newVersion = '<b>To CryptPad αναβαθμίστηκε!</b><br>' +
'Δείτε τι καινούριο υπάρχει στην πιο πρόσφατη έκδοση:<br>'+
'<a href="https://github.com/xwiki-labs/cryptpad/releases/tag/{0}" target="_blank">Σημειώσεις κυκλοφορίας του CryptPad {0}</a>';
out.upgrade = "Αναβάθμιση";
out.upgradeTitle = "Αναβαθμίστε τον λογαριασμό σας για να αυξήσετε το όριο αποθηκευτικού χώρου";
out.upgradeAccount = "Αναβάθμιση λογαριασμού";
out.MB = "MB";
out.GB = "GB";
out.KB = "KB";
out.supportCryptpad = "Υποστηρίξτε το CryptPad";
out.formattedMB = "{0} MB";
out.formattedGB = "{0} GB";
out.formattedKB = "{0} KB";
out.greenLight = "Όλα λειτουργούν σωστά";
out.orangeLight = "Η αργή σύνδεση ίσως έχει αντίκτυπο στην διάδραση";
out.redLight = "Έχετε αποσυνδεθεί από τη συνεδρία";
out.pinLimitReached = "Έχετε φτάσει το όριο αποθηκευτικού χώρου";
out.updated_0_pinLimitReachedAlert = "Έχετε φτάσει το όριο αποθηκευτικού χώρου. Τα νέα pads δεν θα αποθηκευτούν στο CryptDrive σας.<br>" +
'Μπορείτε είτε να διαγράψετε αρχεία από το CryptDrive σας, είτε να <a href="https://accounts.cryptpad.fr/#!on={0}" target="_blank">αναβαθμισετε τον λογαριασμό σας</a> για να αυξήσετε το όριο αποθήκευσης.';
out.pinLimitReachedAlert = out.updated_0_pinLimitReachedAlert;
out.pinLimitReachedAlertNoAccounts = out.pinLimitReached;
out.pinLimitNotPinned = "Έχετε φτάσει το όριο αποθηκευτικού χώρου.<br>"+
"Αυτό το pad δεν θα αποθηκευτεί στο CryptDrive σας.";
out.pinLimitDrive = "Έχετε φτάσει το όριο αποθηκευτικού χώρου.<br>" +
"Δεν μπορείτε να δημιουργήσετε νέα pads.";
out.moreActions = "Περισσότερες επιλογές";
out.importButton = "Εισαγωγή";
out.importButtonTitle = 'Εισάγετε ένα pad από τοπικό αρχείο';
out.exportButton = "Εξαγωγή";
out.exportButtonTitle = 'Εξάγετε αυτό το pad σε τοπικό αρχείο';
out.exportPrompt = 'Πως θα θέλατε να ονομάσετε το αρχείο σας;';
out.changeNamePrompt = 'Αλλάξτε το όνομα σας (αφήστε το κενό για ανωνυμία): ';
out.user_rename = "Αλλαγή εμφανιζόμενου ονόματος";
out.user_displayName = "Εμφανιζόμενο όνομα";
out.user_accountName = "Όνομα χρήστη";
out.clickToEdit = "Κάντε \"κλικ\" για επεξεργασία";
out.saveTitle = "Αποθήκευση τίτλου (enter)";
out.forgetButton = "Διαγραφή";
out.forgetButtonTitle = 'Μετακίνηση αυτού του pad στον κάδο';
out.forgetPrompt = 'Πατώντας OK θα μετακινηθεί αυτό το pad στον κάδο ανακύκλωσης. Είστε σίγουρος;';
out.movedToTrash = 'Το pad μετακινήθηκε στον κάδο.<br><a href="/drive/">Μεταφερθείτε στο CryptDrive σας</a>';
out.shareButton = 'Διαμοιρασμός';
out.shareSuccess = 'Ο σύνδεσμος αντιγράφηκε στην προσωρινή μνήμη';
out.userListButton = "Λίστα χρηστών";
out.userAccountButton = "Ο λογαριασμός σας";
out.newButton = 'Νέο';
out.newButtonTitle = 'Δημιουργία νέου pad';
out.uploadButton = 'Μεταφόρτωση αρχείου';
out.uploadButtonTitle = 'Μεταφόρτωση νέου αρχείου στον τρέχοντα φάκελο';
out.saveTemplateButton = "Αποθήκευση ως πρότυπο";
out.saveTemplatePrompt = "Επιλέξτε τίτλο για αυτό το πρότυπο";
out.templateSaved = "Το πρότυπο αποθηκεύτηκε!";
out.selectTemplate = "Επιλέξτε ένα πρότυπο ή πατήστε escape";
out.useTemplate = "Έχετε διαθέσιμα πρότυπα για αυτό το είδος pad. Θα θέλετε να χρησιμοποιήσετε κάποιο;"; //Would you like to "You have available templates for this type of pad. Do you want to use one?";
out.useTemplateOK = 'Επιλέξτε ένα πρότυπο (Enter)';
out.useTemplateCancel = 'Ξεκινήστε από το μηδέν (Esc)';
out.previewButtonTitle = "Προβολή ή απόκρυψη προεπισκόπησης της μορφοποίησης Markdown";
out.presentButtonTitle = "Είσοδος σε λειτουργία παρουσίασης";
out.backgroundButtonTitle = 'Αλλάξτε το χρώμα παρασκηνίου στην παρουσίαση';
out.colorButtonTitle = 'Αλλάξτε το χρώμα κειμένου στην λειτουργία παρουσίασης';
out.printText = "Εκτύπωση";
out.printButton = "Εκτύπωση (enter)";
out.printButtonTitle = "Εκτυπώστε τις διαφάνειές σας ή εξάγετε τες ως αρχείο PDF";
out.printOptions = "Επιλογές διάταξης";
out.printSlideNumber = "Εμφάνιση του αριθμού διαφάνειας";
out.printDate = "Εμφάνιση της ημερομηνίας";
out.printTitle = "Εμφάνιση του τίτλου του pad";
out.printCSS = "Προσαρμοσμένες ρυθμίσεις εμφάνισης (CSS):";
out.printTransition = "Ενεργοποίηση κινούμενων μεταβάσεων";
out.filePickerButton = "Ενσωμάτωση αρχείου από το CryptDrive σας";
out.filePicker_close = "Κλείσιμο";
out.filePicker_description = "Επιλέξτε ένα αρχείο από το CryptDrive σας για ενσωμάτωση ή μεταφορτώστε ένα καινούριο";
out.filePicker_filter = "Προβολή αρχείων κατά όνομα";
out.or = 'ή';
out.tags_title = "Ετικέτες (για εσάς μόνο)";
out.tags_add = "Ενημερώστε τις ετικέτες αυτής της σελίδας";
out.tags_searchHint = "Βρείτε αρχεία από τις ετικέτες τους ψάχνωντας στο CryptDrive σας";
out.tags_searchHint = "Ξεκινήστε μια αναζήτηση με το σύμβολο # στο CryptDrive σας για να βρείτε pads με ετικέτες.";
out.tags_notShared = "Οι ετικέτες σας δεν μοιράζονται με άλλους χρήστες";
out.tags_duplicate = "Διπλή ετικέτα: {0}";
out.tags_noentry = "Δεν μπορείτε να βάλετε ετικέτα σε διεγραμένο pad!";
out.slideOptionsText = "Επιλογές";
out.slideOptionsTitle = "Προσαρμόστε τις διαφάνειες σας";
out.slideOptionsButton = "Αποθήκευση (enter)";
out.slide_invalidLess = "Μη έγκυρη προσαρμογή";
out.languageButton = "Γλώσσα";
out.languageButtonTitle = "Επιλέξτε τη γλώσσα που θα χρησιμοποιήσετε για την επισήμανση σύνταξης";
out.themeButton = "Θέμα";
out.themeButtonTitle = "Επιλέξτε το θέμα που θα χρησιμοποιήσετε για την επεξεργασία κώδικα και διαφανειών";
out.editShare = "Σύνδεσμος επεξεργασίας";
out.editShareTitle = "Αντιγραφή του συνδέσμου επεξεργασίας στην προσωρινή μνήμη";
out.editOpen = "Άνοιγμα του συνδέσμου επεξεργασίας σε νέα καρτέλα";
out.editOpenTitle = "Άνοιγμα αυτού του pad για επεξεργασία σε νέα καρτέλα";
out.viewShare = "Σύνδεσμος μόνο για ανάγνωση";
out.viewShareTitle = "Αντιγραφή του συνδέσμου μόνο για ανάγνωση στην προσωρινή μνήμη";
out.viewOpen = "Άνοιγμα του συνδέσμου μόνο για ανάγνωση σε νέα καρτέλα";
out.viewOpenTitle = "Άνοιγμα αυτού του pad μόνο για ανάγνωση σε νέα καρτέλα";
out.fileShare = "Αντιγραφή συνδέσμου";
out.getEmbedCode = "Κώδικας ενσωμάτωσης";
out.viewEmbedTitle = "Ενσωματώστε αυτό το pad σε μία εξωτερική σελίδα";
out.viewEmbedTag = "Για να ενσωματώσετε αυτό το pad, συμπεριλάβετε αυτό το iframe στη σελίδα σας, στο σημείο που θέλετε. Μπορείτε να το διαμορφώσετε χρησιμοποιώντας CSS η HTML παραμέτρους.";
out.fileEmbedTitle = "Ενσωματώστε το αρχείο σε μια εξωτερική σελίδα";
out.fileEmbedScript = "Για να ενσωματώσετε αυτό το αρχείο, συμπεριλάβετε αυτό το script στη σελίδα σας για να φορτωθεί το Media Tag:";
out.fileEmbedTag = "Έπειτα τοποθετήστε αυτό το Media Tag στο σημείο της σελίδας που επιθυμείτε να γίνει ενσωμάτωση:";
out.notifyJoined = "Ο/Η {0} εισήλθε στη συνεργατική συνεδρία";
out.notifyRenamed = "Ο/Η {0} είναι τώρα γνωστός/η ως {1}";
out.notifyLeft = "Ο/Η {0} αποχώρησε από τη συνεργατική συνεδρία";
out.okButton = 'OK (enter)';
out.cancel = "Ακύρωση";
out.cancelButton = 'Ακύρωση (esc)';
out.doNotAskAgain = "Να μην ρωτηθώ ξανά (Esc)";
out.historyText = "Ιστορικό";
out.historyButton = "Εμφάνιση ιστορικού του εγγράφου";
out.history_next = "Μετάβαση στην επόμενη έκδοση";
out.history_prev = "Μετάβαση στην προηγούμενη έκδοση";
out.history_goTo = "Μετάβαση στην επιλεγμένη έκδοση";
out.history_close = "Επιστροφή";
out.history_closeTitle = "Κλείσιμο ιστορικού";
out.history_restore = "Επαναφορά";
out.history_restoreTitle = "Επαναφορά της επιλεγμένης έκδοσης του εγγράφου";
out.history_restorePrompt = "Είστε σίγουροι πως θέλετε να αντικαταστήσετε την τρέχουσα έκδοση του εγγράφου με την επιλεγμένη;";
out.history_restoreDone = "Έγινε επαναφορά του εγγράφου";
out.history_version = "Έκδοση:";
// Ckeditor
out.openLinkInNewTab = "Άνοιγμα συνδέσμου σε νέα καρτέλα";
out.pad_mediatagTitle = "Ρυθμίσεις Media-Tag";
out.pad_mediatagWidth = "Πλάτος (px)";
out.pad_mediatagHeight = "Ύψος (px)";
// Polls
out.poll_title = "Zero Knowledge επιλογή ημερομηνίας";
out.poll_subtitle = "Zero Knowledge, <em>πραγματικού χρόνου</em> οργάνωση";
out.poll_p_save = "Οι ρυθμίσεις σας ενημερώνονται άμεσα, έτσι δεν χρειάζεται ποτέ να αποθηκεύσετε.";
out.poll_p_encryption = "Όλο το περιεχόμενο είναι κρυπτογραφημένο και έτσι μόνο τα άτομα που έχουν τον σύνδεσμο μπορούν να έχουν πρόσβαση σε αυτό. Ούτε ο διακομιστής δεν μπορεί να δει τι γράφετε.";
out.wizardLog = "Πατήστε το κουμπί πάνω αριστερά για να επιστρέψετε στη δημοσκόπηση σας";
out.wizardTitle = "Χρησιμοποιήστε τον οδηγό για να δημιουργήσετε τη δημοσκόπηση σας";
out.wizardConfirm = "Είσαστε έτοιμοι να προσθέσετε αυτές τις επιλογές στη δημοσκόπηση σας;";
out.poll_publish_button = "Δημοσίευση";
out.poll_admin_button = "Διαχείριση";
out.poll_create_user = "Προσθέστε έναν νέο χρήστη";
out.poll_create_option = "Προσθέστε μια νέα επιλογή";
out.poll_commit = "Υποβολή";
out.poll_closeWizardButton = "Κλείσιμο οδηγού";
out.poll_closeWizardButtonTitle = "Κλείσιμο οδηγού";
out.poll_wizardComputeButton = "Υπολογισμός επιλογών";
out.poll_wizardClearButton = "Εκκαθάριση πεδίων";
out.poll_wizardDescription = "Αυτόματα δημιουργήστε έναν αριθμό επιλογών εισάγοντας όσες ημερομηνίες και χρόνους θέλετε";
out.poll_wizardAddDateButton = "+ Ημερομηνίες";
out.poll_wizardAddTimeButton = "+ Χρόνους";
out.poll_optionPlaceholder = "Επιλογή";
out.poll_userPlaceholder = "Το όνομα σας";
out.poll_removeOption = "Είστε σίγουροι πως θέλετε να αφαιρέσετε αυτή την επιλογή;";
out.poll_removeUser = "Είστε σίγουροι πως θέλετε να αφαιρέσετε αυτόν τον χρήστη;";
out.poll_titleHint = "Τίτλος";
out.poll_descriptionHint = "Περιγράψτε τη δημοσκόπηση σας και χρησιμοποιήστε το κουμπί ✓ (δημοσίευση) όταν έχετε τελειώσει.\n" +
"Η περιγραφή μπορεί να γραφτεί χρησιμοποιώντας μορφοποίηση markdown και μπορείτε να ενσωματώσετε γραφικά στοιχεία από το CryptDrive σας.\n" +
"Οποιοσδήποτε με τον σύνδεσμο της δημοσκόπησης μπορεί να αλλάξει την περιγραφή, αλλά αυτό δεν συνίσταται.";
out.poll_remove = "Αφαίρεση";
out.poll_edit = "Επεξεργασία";
out.poll_locked = "Κλείδωμα";
out.poll_unlocked = "Ξεκλείδωμα";
out.poll_show_help_button = "Εμφάνιση βοήθειας";
out.poll_hide_help_button = "Απόκρυψη βοήθειας";
out.poll_bookmark_col = 'Αποθηκεύστε αυτή τη στήλη ώστε να είναι πάντα ξεκλείδωτη και εμφανής κατά την εκκίνηση για εσάς';
out.poll_bookmarked_col = 'Αυτή είναι η στήλη σελιδοδεικτών σας. Θα είναι πάντα ξεκλείδωτη και εμφανής κατά την εκκίνηση για εσάς.';
out.poll_total = 'Σύνολο';
out.poll_comment_list = "Σχόλια";
out.poll_comment_add = "Κάντε ένα σχόλιο";
out.poll_comment_submit = "Αποστολή";
out.poll_comment_remove = "Διαγράψτε αυτό το σχόλιο";
out.poll_comment_placeholder = "Το σχόλιό σας";
out.poll_comment_disabled = "Δημοσιεύστε αυτή τη δημοσκόπηση χρησημοποιώντας το κουμπί ✓ για να ενεργοποιηθεί ο σχολιασμός.";
// Canvas
out.canvas_clear = "Εκκαθάριση";
out.canvas_delete = "Διαγραφή επιλογής";
out.canvas_disable = "Απενεργοποίηση σχεδιασμού";
out.canvas_enable = "Ενεργοποίηση σχεδιασμού";
out.canvas_width = "Πλάτος";
out.canvas_opacity = "Αδιαφάνεια";
out.canvas_opacityLabel = "Αδιαφάνεια: {0}";
out.canvas_widthLabel = "Πλάτος: {0}";
out.canvas_saveToDrive = "Αποθηκεύστε αυτή την εικόνα ως αρχείο στο CryptDrive σας";
out.canvas_currentBrush = "Τρέχων πινέλο";
out.canvas_chooseColor = "Επιλογή χρώματος";
out.canvas_imageEmbed = "Εισάγετε μια εικόνα από τον υπολογιστή σας";
// Profile
out.profileButton = "Προφίλ"; // dropdown menu
out.profile_urlPlaceholder = 'Διεύθυνση';
out.profile_namePlaceholder = 'Το όνομα που θα εμφανίζετε στο προφίλ σας';
out.profile_avatar = "Αβατάρ";
out.profile_upload = " Μεταφορτώστε ένα νέο αβατάρ";
out.profile_uploadSizeError = "Σφάλμα: το αβατάρ σας πρέπει να είναι μικρότερο από {0}";
out.profile_uploadTypeError = "Σφάλμα: αυτό το είδος αρχείου δεν επιτρέπεται. Επιτρεπόμενα αρχεία: {0}";
out.profile_error = "Σφάλμα κατά τη δημιουργία του προφίλ σας: {0}";
out.profile_register = "Πρέπει να εγγραφείτε για να δημιουργήσετε προφίλ!";
out.profile_create = "Δημιουργήστε προφίλ";
out.profile_description = "Περιγραφή";
out.profile_fieldSaved = 'Η καινούρια καταχώρηση αποθηκεύτηκε: {0}';
out.profile_inviteButton = "Σύνδεση";
out.profile_inviteButtonTitle ='Δημιουργήστε έναν σύνδεσμο για να προσκαλέσετε αυτόν το χρήστη να συνδεθεί μαζί σας.';
out.profile_inviteExplanation = "Πατώντας <strong>OK</strong> θα δημιουργηθεί ένας σύνδεσμος προς μια ασφαλή συνεδρία επικοινωνίας όπου <em>μόνο ο/η {0} θα μπορεί να ανοίξει.</em><br><br>Ο σύνδεσμος θα αντιγραφεί στην προσωρινή μνήμη και μπορεί να διαμοιραστεί δημόσια.";
out.profile_viewMyProfile = "Προβολή του προφίλ μου";
// contacts/userlist
out.userlist_addAsFriendTitle = 'Προσθήκη του/της "{0}" ως επαφή';
out.userlist_thisIsYou = 'Αυτός είστε εσείς ("{0}")';
out.userlist_pending = "Εκρεμμεί...";
out.contacts_title = "Επαφές";
out.contacts_addError = 'Σφάλμα κατά την προσθήκη αυτής της επαφής στη λίστα';
out.contacts_added = 'Η επαφή αποδέχτηκε την πρόσκληση.';
out.contacts_rejected = 'Η επαφή απέρριψε την πρόσκληση';
out.contacts_request = 'Ο/Η <em>{0}</em> Θα ήθελε να σας προσθέσει ως επαφή. <b>Αποδοχή<b>;';
out.contacts_send = 'Αποστολή';
out.contacts_remove = 'Αφαίρεση αυτής της επαφής';
out.contacts_confirmRemove = 'Είσαστε σίγουροι πως θέλετε να αφαιρέσετε τον/την <em>{0}</em> από τις επαφές σας;';
out.contacts_typeHere = "Πληκτρολογήστε ένα μήνυμα εδώ...";
out.contacts_info1 = "Αυτές είναι οι επαφές σας. Από εδώ, μπορείτε να:";
out.contacts_info2 = "Πατήσετε στο εικονίδιο της επαφής για να συνομιλήσετε μαζί τους";
out.contacts_info3 = "Κάνετε \"διπλό κλικ\" στο εικονίδιο για να δείτε το προφίλ τους";
out.contacts_info4 = "Ο κάθε συμμετέχων μπορεί να διαγράψει μόνιμα το ιστορικό μιας συνομιλίας";
out.contacts_removeHistoryTitle = 'Εκκαθάριση του ιστορικού συνομιλίας';
out.contacts_confirmRemoveHistory = 'Είστε σίγουροι πως θέλετε να διαγράψετε μόνιμα το ιστορικό; Τα δεδομένα δεν μπορούν να επαναφερθούν';
out.contacts_removeHistoryServerError = 'Προέκυψε ένα σφάλμα κατά της εκκαθάριση του ιστορικού. Δοκιμάστε ξανά αργότερα';
out.contacts_fetchHistory = "Ανάκτηση παλαιότερου ιστορικού";
// File manager
out.fm_rootName = "Έγγραφα";
out.fm_trashName = "Σκουπίδια";
out.fm_unsortedName = "Αταξινόμητα";
out.fm_filesDataName = "Όλα τα αρχεία";
out.fm_templateName = "Πρότυπα";
out.fm_searchName = "Αναζήτηση";
out.fm_recentPadsName = "Πρόσφατα pads";
out.fm_searchPlaceholder = "Αναζήτηση...";
out.fm_newButton = "Νέο";
out.fm_newButtonTitle = "Δημιουργήστε ένα νέο pad ή φάκελο, εισάγετε ένα αρχείο στον τρέχοντα φάκελο";
out.fm_newFolder = "Νέος φάκελος";
out.fm_newFile = "Νέο pad";
out.fm_folder = "Φάκελος";
out.fm_folderName = "Όνομα φακέλου";
out.fm_numberOfFolders = "# φακέλων";
out.fm_numberOfFiles = "# αρχείων";
out.fm_fileName = "Όνομα αρχείου";
out.fm_title = "Τίτλος";
out.fm_type = "Τύπος";
out.fm_lastAccess = "Τελευταία προσπέλαση";
out.fm_creation = "Δημιουργία";
out.fm_forbidden = "Απαγορευμένη ενέργεια";
out.fm_originalPath = "Πρωτότυπη διαδρομή";
out.fm_openParent = "Προβολή στον φάκελο";
out.fm_noname = "Έγγραφο χωρίς τίτλο";
out.fm_emptyTrashDialog = "Θέλετε σίγουρα να αδειάσετε τον κάδο;";
out.fm_removeSeveralPermanentlyDialog = "Θέλετε σίγουρα να αφαιρέσετε αυτά τα {0} αντικείμενα από το CryptDrive σας μόνιμα;";
out.fm_removePermanentlyDialog = "Θέλετε σίγουρα να αφαιρέσετε αυτό το αντικείμενο από το CryptDrive σας μόνιμα;";
out.fm_removeSeveralDialog = "Θέλετε σίγουρα να μετακινήσετε αυτά τα {0} αντικείμενα στον κάδο;";
out.fm_removeDialog = "Θέλετε σίγουρα να μετακινήσετε το {0} στον κάδο;";
out.fm_restoreDialog = "Θέλετε σίγουρα να επαναφέρετε το {0} στην προηγούμενη τοποθεσία του;";
out.fm_unknownFolderError = "Η επιλεγμένη ή πιο πρόσφατη τοποθεσία δεν υπάρχει πλέον. Γίνεται άνοιγμα του τρέχοντα φακέλου...";
out.fm_contextMenuError = "Αδυναμία ανοίγματος μενού για αυτό το αντικείμενο. Αν το πρόβλημα επιμείνει, δοκιμάστε να επαναφορτώσετε τη σελίδα.";
out.fm_selectError = "Αδυναμία επιλογής του συγκεκριμένου αντικειμένου. Αν το πρόβλημα επιμείνει, δοκιμάστε να επαναφορτώσετε τη σελίδα.";
out.fm_categoryError = "Αδυναμία ανοίγματος της επιλεγμένης κατηγορίας, γίνεται προβολή του γονικού φακέλου.";
out.fm_info_root = "Δημιουργήστε εδώ όσους υποφακέλους θέλετε για να ταξινομήσετε τα αρχεία σας.";
out.fm_info_unsorted = 'Περιέχει όλα τα αρχεία που έχετε επισκεφτεί αλλά δεν έχουν ταξινομηθεί στα "Έγγραφα", ούτε έχουν μετακινηθεί στα "Σκουπίδια".'; // "My Documents" should match with the "out.fm_rootName" key, and "Trash" with "out.fm_trashName"
out.fm_info_template = 'Περιέχει όλα τα pads που έχουν αποθηκευτεί ως πρότυπα και μπορείτε να ξαναχρησιμοποιήσετε όταν δημιουργείτε ένα νέο pad.';
out.fm_info_recent = "Λίστα των πρόσφατα τροποποιημένων ή ανοιγμένων pads.";
out.updated_0_fm_info_trash = 'Αδειάστε τον κάδο σας για να απελευθερώσετε χώρο στο CryptDrive σας.';
out.fm_info_trash = out.updated_0_fm_info_trash;
out.fm_info_allFiles = 'Περιέχει όλα τα αρχεία από τα "Έγγραφα", "Αταξινόμητα" και "Σκουπίδια". Δεν μπορείτε να μετακινήσετε ή να αφαιρέσετε αρχεία από εδώ.'; // Same here
out.fm_info_anonymous = 'Δεν έχετε συνδεθεί, οπότε τα pads σας θα διαγραφούν μετά από 3 μήνες (<a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">μάθετε περισσότερα</a>). ' +
'<a href="/register/">Εγγραφείτε</a> ή <a href="/login/">Συνδεθείτε</a> για να τα κρατήσετε επ\' αόριστον.';
out.fm_alert_backupUrl = "Σύνδεσμος ασφαλείας για αυτόν τον αποθηκευτικό χώρο.<br>" +
"Συνίσταται <strong>ιδιαιτέρως</strong> να τον κρατήσετε μυστικό.<br>" +
"Μπορείτε να τον χρησιμοποιήσετε για να ανακτήσετε όλα σας τα αρχεία σε περίπτωση που διαγραφεί η μνήμη του περιηγητή σας.<br>" +
"Οποιοσδήποτε με αυτόν τον σύνδεσμο μπορεί να επεξεργαστεί ή να αφαιρέσει όλα τα αρχεία σας στον διαχειριστή αρχείων.<br>";
out.fm_alert_anonymous = "Γεια σας! Αυτή τη στιγμή χρησιμοποιείτε το CryptPad ανώνυμα, αυτό είναι ok αλλά τα pads σας ίσως διαγραφούν μετά από ένα διάστημα " +
"αδράνειας. Έχουμε απενεργοποιήσει προηγμένες λειτουργίες του αποθηκευτικού χώρου για τους ανώνυμους χρήστες επειδή θέλουμε να καταστήσουμε ξεκάθαρο πως " +
'δεν είναι ένα ασφαλές μέρος για να αποθηκεύετε πράγματα. Μπορείτε να <a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">διαβάσετε περισσότερα</a> σχετικά ' +
'με το γιατί το κάνουμε αυτό και γιατί θα έπρεπε να <a href="/register/">Εγγραφείτε</a> ή να <a href="/login/">Συνδεθείτε</a>.';
out.fm_backup_title = 'Σύνδεσμος ασφαλείας';
out.fm_nameFile = 'Πως θα θέλατε να ονομάσετε αυτό το αρχείο;';
out.fm_error_cantPin = "Εσωτερικό σφάλμα διακομιστή. Παρακαλούμε επαναφορτώστε τη σελίδα και προσπαθήστε ξανά.";
out.fm_viewListButton = "Προβολή λίστας";
out.fm_viewGridButton = "Προβολή πλέγματος";
out.fm_renamedPad = "Έχετε ορίσει ένα προσαρμοσμένο όνομα για αυτό το pad. Ο διαμοιραζόμενος τίτλος του είναι:<br><b>{0}</b>";
out.fm_prop_tagsList = "Ετικέτες";
out.fm_burnThisDriveButton = "Διαγραφή όλων των πληροφοριών που έχουν αποθηκευτεί από το CryptPad στον περιηγητή σας";
out.fm_burnThisDrive = "Είστε σίγουροι πως θέλετε να διαγράψετε όλα όσα έχουν αποθηκευτεί από το CryptPad στον περιηγητή σας;<br>" +
"Αυτό θα αφαιρέσει το CryptDrive σας και το ιστορικό του από τον περιηγητή σας, αλλά τα pads σας θα εξακολουθήσουν να υπάρχουν (κρυπτογραφημένα) στον διακομιστή μας.";
// File - Context menu
out.fc_newfolder = "Νέος φάκελος";
out.fc_rename = "Μετονομασία";
out.fc_open = "Άνοιγμα";
out.fc_open_ro = "Άνοιγμα για προβολή μόνο";
out.fc_delete = "Μετακίνηση στον κάδο";
out.fc_restore = "Επαναφορά";
out.fc_remove = "Αφαίρεση από το CryptDrive σας";
out.fc_empty = "Άδειασμα του κάδου";
out.fc_prop = "Ιδιότητες";
out.fc_hashtag = "Ετικέτες";
out.fc_sizeInKilobytes = "Μέγεθος σε Kilobytes";
// fileObject.js (logs)
out.fo_moveUnsortedError = "Δεν μπορείτε να μετακινήσετε έναν φάκελο στη λίστα των αταξινόμητων pads";
out.fo_existingNameError = "Το όνομα χρησμοποιείται ήδη σε αυτή την τοποθεσία. Παρακαλώ επιλέξτε ένα άλλο.";
out.fo_moveFolderToChildError = "Δεν μπορείτε να μετακινήσετε έναν φάκελο μέσα σε κάποιο από τα περιεχόμενα του";
out.fo_unableToRestore = "Αδυναμία επαναφοράς αυτού του αρχείο στην αρχική τοποθεσία του. Μπορείτε να δοκιμάσετε να το μετακινήσετε σε μια νέα τοποθεσία.";
out.fo_unavailableName = "Ένα αρχείο ή ένας φάκελος με το ίδιο όνομα υπάρχει ήδη στη νέα τοποθεσία. Μετονομάστε το αρχείο και προσπαθήστε ξανά.";
out.fs_migration = "Το CryptDrive σας αναβαθμίστηκε σε μια νεότερη έκδοση. Ως αποτέλεσμα, η τρέχουσα σελίδα θα πρέπει να επαναφορτωθεί.<br><strong>Παρακαλούμε επαναφορτώστε τη σελίδα για να συνεχίσετε να την χρησιμοποιείτε.</strong>";
// login
out.login_login = "Σύνδεση";
out.login_makeAPad = 'Δημιουργήστε ένα pad ανώνυμα';
out.login_nologin = "Περιηγηθείτε στα τοπικά pads";
out.login_register = "Εγγραφή";
out.logoutButton = "Αποσύνδεση";
out.settingsButton = "Ρυθμίσεις";
out.login_username = "Όνομα χρήστη";
out.login_password = "Κωδικός";
out.login_confirm = "Επιβεβαίωση κωδικού";
out.login_remember = "Απομνημόνευση";
out.login_hashing = "Κρυπτογραφούμε τον κωδικό σας, αυτό μπορεί να πάρει λίγη ώρα.";
out.login_hello = 'Καλησπέρα {0},'; // {0} is the username
out.login_helloNoName = 'Καλησπέρα,';
out.login_accessDrive = 'Περιηγήθείτε στον αποθηκευτικό σας χώρο';
out.login_orNoLogin = 'ή';
out.login_noSuchUser = 'Μη έγκυρο όνομα χρήστη ή λάθος κωδικός. Προσπαθήστε ξανά, ή εγγραφείτε';
out.login_invalUser = 'Απαιτείται όνομα χρήστη';
out.login_invalPass = 'Απαιτείται κωδικός';
out.login_unhandledError = 'Προέκυψε ένα μη αναμενόμενο σφάλμα :(';
out.register_importRecent = "Εισαγωγή ιστορικού (Συνίσταται)";
out.register_acceptTerms = "Αποδέχομαι <a href='/terms.html' tabindex='-1'>τους όρους χρήσης</a> της υπηρεσίας";
out.register_passwordsDontMatch = "Οι κωδικοί δεν ταιριάζουν!";
out.register_passwordTooShort = "Οι κωδικοί πρέπει να αποτελούνται από τουλάχιστον {0} χαρακτήρες.";
out.register_mustAcceptTerms = "Πρέπει να αποδεχτείτε τους όρους της υπηρεσίας.";
out.register_mustRememberPass = "Δεν μπορούμε να επαναφέρουμε τον κωδικό σας αν τον ξεχάσετε. Είναι πολύ σημαντικό να τον θυμάστε! Παρακαλούμε πατήστε στο κουτάκι για επιβεβαίωση.";
out.register_header = "Καλώς ήρθατε στο CryptPad";
out.register_explanation = [
"<h3>Ας δούμε κάνα-δυο πράγματα πρώτα:</h3>",
"<ul class='list-unstyled'>",
"<li><i class='fa fa-info-circle'> </i> Ο κωδικός σας είναι το μυστικό κλειδί που κρυπτογραφεί όλα τα pads σας. Αν το χάσετε, δεν υπάρχει τρόπος να επαναφέρουμε τα δεδομένα σας.</li>",
"<li><i class='fa fa-info-circle'> </i> Μπορείτε να εισάγετε τα pads που ανοίξατε πρόσφατα στον περιηγητή σας ώστε να τα έχετε στον λογαριασμό σας.</li>",
"<li><i class='fa fa-info-circle'> </i> Αν χρησιμοποιείτε έναν κοινόχρηστο υπολογιστή, θα πρέπει να αποσυνδεθείτε όταν τελειώσετε, το να κλείσετε την καρτέλα δεν είναι αρκετό.</li>",
"</ul>"
].join('');
out.register_writtenPassword = "Έχω σημειώσει το όνομα χρήστη και τον κωδικό μου, συνέχεια";
out.register_cancel = "Επιστροφή";
out.register_warning = "Zero Knowledge σημαίνει πως δεν μπορούμε να επαναφέρουμε τον λογαριασμό σας αν χάσετε τον κωδικό σας.";
out.register_alreadyRegistered = "Αυτός ο χρήστης υπάρχει ήδη, μήπως θέλετε να συνδεθείτε;";
// Settings
out.settings_cat_account = "Λογαριασμός";
out.settings_cat_drive = "CryptDrive";
out.settings_cat_code = "Κώδικας";
out.settings_title = "Ρυθμίσεις";
out.settings_save = "Αποθήκευση";
out.settings_backupCategory = "Αντίγραφο ασφαλείας";
out.settings_backupTitle = "Αποθηκεύστε ή επαναφέρετε όλα σας τα δεδομένα";
out.settings_backup = "Δημιουργία αντιγράφου ασφαλείας";
out.settings_restore = "Επαναφορά από αντίγραφο ασφαλείας";
out.settings_resetNewTitle = "Εκκαθάριση του CryptDrive";
out.settings_resetButton = "Αφαίρεση";
out.settings_reset = "Αφαίρεση όλων των αρχείων και φακέλων από το CryptDrive σας";
out.settings_resetPrompt = "Αυτή η ενέργεια θα αφαιρέσει όλα τα pads από τον αποθηκευτικό σας χώρο.<br>"+
"Θέλετε σίγουρα να συνεχίσετε;<br>" +
"Πληκτρολογήστε “<em>I love CryptPad</em>” για επιβεβαίωση.";
out.settings_resetDone = "Ο αποθηκευτικός σας χώρος είναι πλέον άδειος!";
out.settings_resetError = "Λάθος κείμενο επιβεβαίωσης. Το CryptDrive σας δεν έχει αλλαχθεί.";
out.settings_resetTipsAction = "Επαναφορά";
out.settings_resetTips = "Συμβουλές";
out.settings_resetTipsButton = "Επαναφέρετε όλες τις διαθέσιμες συμβουλές για το CryptDrive";
out.settings_resetTipsDone = "Όλες οι συμβουλές είναι πάλι ορατές.";
out.settings_thumbnails = "Μικρογραφίες";
out.settings_disableThumbnailsAction = "Απενεργοποίηση μικρογραφιών στο CryptDrive σας";
out.settings_disableThumbnailsDescription = "Οι μικρογραφίες δημιουργούνται αυτόματα και αποθηκεύονται στον περιηγητή σας όταν επισκέπτεστε ένα νέο pad. Μπορείτε να απενεργοποιήσετε αυτό το χαρακτηριστικό εδώ.";
out.settings_resetThumbnailsAction = "Εκκαθάριση";
out.settings_resetThumbnailsDescription = "Εκκαθάριση όλων των μικρογραφιών που έχουν αποθηκευτεί στον περιηγητή σας.";
out.settings_resetThumbnailsDone = "Όλες οι μικρογραφίες έχουν διαγραφεί.";
out.settings_importTitle = "Εισάγετε τα πρόσφατα pads αυτού του περιηγητή στο CryptDrive σας";
out.settings_import = "Εισαγωγή";
out.settings_importConfirm = "Είσαστε σίγουρος ότι θέλετε να εισάγετε τα πρόσφατα pads από αυτόν τον περιηγητή στον λογαριασμό χρήστη σας στο CryptDrive?";
out.settings_importDone = "Εισαγωγή ολοκληρώθηκε";
out.settings_userFeedbackTitle = "Αναπληροφόρηση";
out.settings_userFeedbackHint1 = "Το CryptPad αποστέλλει κάποιες πολύ βασικές πληροφορίες σ' εμάς, ώστε να μας ενημερώσει για το πως μπορούμε να βελτιώσουμε την εμπειρία σας.";
out.settings_userFeedbackHint2 = "Το περιεχόμενο των pads σας δεν διαμοιράζεται ποτέ μαζί μας.";
out.settings_userFeedback = "Ενεργοποίηση αναπληροφόρησης χρήστη";
out.settings_anonymous = "Δεν είσαστε συνδεδεμένος. Οι τρέχουσες ρυθμίσεις ισχύουν μόνο για τον συγκεκριμένο περιηγητή.";
out.settings_publicSigningKey = "Δημόσιο κλειδί κρυπτογράφησης";
out.settings_usage = "Χρήση";
out.settings_usageTitle = "Δείτε ολόκληρο το μέγεθος των καρφιτσωμένων pads σας σε MB";
out.settings_pinningNotAvailable = "Τα καρφιτσωμένα pads είναι διαθέσιμα μόνο σε εγγεγραμένους χρήστες.";
out.settings_pinningError = "Κάτι πήγε στραβά";
out.settings_usageAmount = "Τα καρφιτσωμένα pads σας καταναλώνουν σε χώρο {0}MB";
out.settings_logoutEverywhereButton = "Αποσύνδεση";
out.settings_logoutEverywhereTitle = "Αποσύνδεση παντού";
out.settings_logoutEverywhere = "Εξαναγκασμός αποσύνδεσης όλων των άλλων διαδικτυακών συνεδριών.";
out.settings_logoutEverywhereConfirm = "Είσαστε σίγουροι; Θα χρειαστεί να επανασυνδεθείτε σε όλες σας τις συσκευές.";
out.settings_codeIndentation = 'Εσοχές στον επεξεργαστή κώδικα (κενά)';
out.settings_codeUseTabs = "Εισαγωγή εσoχών με χρήση του πλήκτρου tab, αντί κενών";
out.upload_title = "Μεταφόρτωση αρχείου";
out.upload_rename = "Θέλετε να μετονομάσετε το <b>{0}</b> πριν το μεταφορτώσετε στον διακομιστή;<br>" +
"<em>Η κατάληξη του αρχείου ({1}) θα προστεθεί αυτόματα. "+
"Αυτό το όνομα θα είναι μόνιμο και ορατό σε άλλους χρήστες.</em>";
out.upload_serverError = "Λάθος Διακομιστή: δεν μπορούμε να μεταφορτώσουμε το αρχείο σας αυτή την στιγμή.";
out.upload_uploadPending = "Προσπαθείτε ήδη να μεταφορτώσετε κάτι αυτή την στιγμή. Ακύρωση και μεταφόρτωση του κανούριου σας αρχείου;";
out.upload_success = "Το αρχείο σας ({0}) έχει μεταφορτωθεί επιτυχώς κι έχει προστεθεί στον αποθηκευτικό σας χώρο.";
out.upload_notEnoughSpace = "Δεν υπάρχει αρκετός αποθηκευτικός χώρος γι' αυτό το αρχείο στο CryptDrive σας.";
out.upload_tooLarge = "Αυτό το αρχείο ξεπερνάει το μέγιστο μέγεθος μεταφόρτωσης.";
out.upload_choose = "Επιλέξτε ένα αρχείο";
out.upload_pending = "Εκρεμμεί";
out.upload_cancelled = "Ακυρώθηκε";
out.upload_name = "Όνομα αρχείου";
out.upload_size = "Μέγεθος";
out.upload_progress = "Εξέλιξη";
out.upload_mustLogin = "Πρέπει να είσαστε συνδεδεμένος για να μεταφορτώσετε ένα αρχείο";
out.download_button = " Αποκρυπτογράφηση & Κατέβασμα";
out.download_mt_button = "Λήψη";
out.todo_title = "CryptTodo";
out.todo_newTodoNamePlaceholder = "Περιγράψτε την εργασία σας...";
out.todo_newTodoNameTitle = "Προσθέστε την εργασία σας στη λίστα εργασιών";
out.todo_markAsCompleteTitle = "Σημειώστε αυτή την εργασία ως ολοκληρωμένη";
out.todo_markAsIncompleteTitle = "Σημειώστε αυτή την εργασία ως ανολοκλήρωτη";
out.todo_removeTaskTitle = "Αφαιρέστε αυτή την εργασία από την λίστα εργασιών σας";
// pad
out.pad_showToolbar = "Εμφάνιση γραμμής εργαλείων";
out.pad_hideToolbar = "Απόκρυψη γραμμής εργαλείων";
// general warnings
out.warn_notPinned = "Αυτό το pad δεν είναι αποθηκευμένο σε κάποιο CryptDrive. Θα διαγραφεί σε 3 μήνες. <a href='/about.html#pinning'>Μάθετε περισσότερα...</a>";
// markdown toolbar
out.mdToolbar_button = "Εμφάνιση ή απόκρυψη της γραμμής εργαλείων Markdown";
out.mdToolbar_defaultText = "Το κείμενο σας εδώ";
out.mdToolbar_help = "Βοήθεια";
out.mdToolbar_tutorial = "http://www.markdowntutorial.com/";
out.mdToolbar_bold = "Έντονα";
out.mdToolbar_italic = "Πλάγια";
out.mdToolbar_strikethrough = "Διεγραμμένα";
out.mdToolbar_heading = "Επικεφαλίδα";
out.mdToolbar_link = "Σύνδεσμος";
out.mdToolbar_quote = "Παράθεση";
out.mdToolbar_nlist = "Λίστα με αριθμούς";
out.mdToolbar_list = "Λίστα με σημεία";
out.mdToolbar_check = "Λίστα εργασιών";
out.mdToolbar_code = "Κώδικας";
// index.html
//about.html
out.main_p2 = 'Αυτό το εγχείρημα χρησιμοποιεί τον γραφικό επεξεργαστή <a href="http://ckeditor.com/">CKEditor</a>, <a href="https://codemirror.net/">CodeMirror</a>, και την μηχανή πραγματικού χρόνου <a href="https://github.com/xwiki-contrib/chainpad">ChainPad</a>.';
out.main_howitworks_p1 = 'Το CryptPad χρησιμοποιεί μια παραλλαγή του αλγόριθμου <a href="https://en.wikipedia.org/wiki/Operational_transformation">Operational transformation</a> με τον οποίο καταφέρνει να πετύχει κατανεμημένη συναίνεση χρησιμοποιώντας <a href="https://bitcoin.org/bitcoin.pdf">Blockchain</a>, μια δομή που έγινε δημοφιλής μέσω του <a href="https://en.wikipedia.org/wiki/Bitcoin">Bitcoin</a>. Με αυτό τον τρόπο ο αλγόριθμος αποφεύγει την ανάγκη ύπαρξης ενός κεντρικού διακομιστή για να επιλύσει συγκρούσεις ταυτόχρονης επεξεργασίας και χωρίς την ανάγκη επίλυσης αυτών των συγκρούσεων, ο διακομιστής δεν χρειάζεται να έχει γνώση του περιεχομένου που υπάρχει στο pad.';
// contact.html
out.main_about_p2 = 'Αν έχετε απορίες ή σχόλια, επικοινωνήστε μαζί μας!<br/>Μπορείτε να στείλετε <a href="https://twitter.com/cryptpad"><i class="fa fa-twitter"></i>ένα tweet</a>, να δημιουργήσετε ένα θέμα <a href="https://github.com/xwiki-labs/cryptpad/issues/" title="our issue tracker">στο <i class="fa fa-github"></i>GitHub</a>. Ελάτε να πείτε "γεια" <a href="https://riot.im/app/#/room/#cryptpad:matrix.org" title="Matrix">στο <i class="fa fa-comment"></i>Matrix κανάλι μας</a> ή στο IRC (#cryptpad on irc.freenode.net), ή <a href="mailto:research@xwiki.com"><i class="fa fa-envelope"></i>στείλτε μας ένα email</a>.';
out.main_about_p22 = 'Στείλτε μας ένα tweet';
out.main_about_p23 = 'Δημιουργήστε ένα θέμα στο GitHub';
out.main_about_p24 = 'Πείτε "γεια" στο Matrix';
out.main_about_p25 = 'Στείλτε μας ένα email';
out.main_about_p26 = 'Αν έχετε απορίες ή σχόλια, επικοινωνήστε μαζί μας!';
out.main_info = "<h2>Συνεργαστείτε με ασφάλεια</h2> Αναπτύξτε τις ιδέες σας μαζί με κοινά αρχεία όσο η τεχνολογία <strong>Zero Knowledge</strong> εξασφαλίζει την ιδιωτικότητά σας; <strong>ακόμη κι από εμάς</strong>.";
out.main_catch_phrase = "Το Zero Knowledge σύννεφο";
out.main_howitworks = 'Πως Λειτουργεί';
out.main_zeroKnowledge = 'Πρωτόκολλο Zero Knowledge';
out.main_zeroKnowledge_p = "Δεν χρειάζεται να μας εμπιστευθείτε όταν σας λέμε πως <em>δεν θα κοιτάξουμε</em> τα pads σας, διότι με την επαναστατική τεχνολογία Zero Knowledge του CryptPad <em>δεν μπορούμε</em> να τα κοιτάξουμε. Μάθετε περισσότερα για το πως προστατεύουμε την <a href=\"/privacy.html\" title='Privacy'>Ασφάλεια και Ιδιωτικότητά</a> σας.";
out.main_writeItDown = 'Σημειώστε το';
out.main_writeItDown_p = "Τα μεγαλύτερα έργα προέρχονται από τις μικρότερες ιδέες. Καταγράψτε τις στιγμές έμπνευσης και τις απροσδόκητες ιδέες σας διότι ποτέ δεν ξέρετε ποια από αυτές μπορεί να είναι η επόμενη μεγάλη ανακάλυψη.";
out.main_share = 'Μοιραστείτε τον σύνδεσμο, μοιραστείτε το pad';
out.main_share_p = "Αναπτύξτε τις ιδέες σας μαζί: πραγματοποιήστε αποτελεσματικές συναντήσεις, συνεργαστείτε στις λίστες εργασιών και κάντε γρήγορες παρουσιάσεις με όλους τους φίλους σας και από όλες τις συσκευές σας.";
out.main_organize = 'Οργανωθείτε';
out.main_organize_p = "Με το CryptPad Drive, μπορείτε να συγκεντρωθείτε στο τι είναι σημαντικό. Οι φάκελοι σας επιτρέπουν να ελέγχετε τα έργα σας και να έχετε μία συνολική εικόνα για το πως προχωράνε τα πράγματα.";
out.tryIt = 'Δοκιμάστε το!';
out.main_richText = 'Επεξεργαστής Εμπλουτισμένου Κειμένου';
out.main_richText_p = 'Επεξεργαστείτε pads εμπλουτισμένου κειμένου συνεργατικά με την πραγματικού χρόνου Zero Knowledge εφαρμογή μας <a href="http://ckeditor.com" target="_blank">CkEditor</a>.';
out.main_code = 'Επεξεργαστής κώδικα';
out.main_code_p = 'Επεξεργαστείτε κώδικα συνεργατικά με την πραγματικού χρόνου Zero Knowledge εφαρμογή μας <a href="https://www.codemirror.net" target="_blank">CodeMirror</a>.';
out.main_slide = 'Επεξεργαστής Slide';
out.main_slide_p = 'Δημιουργείστε τις παρουσιάσεις σας χρησιμοποιώντας μορφοποίηση Markdown και προβάλλετέ τις στον περιηγητή σας.';
out.main_poll = 'Δημοσκοπήσεις';
out.main_poll_p = 'Προγραμματίστε την συνάντησή σας ή την δραστηριότητά σας, ή ψηφίστε την καλύτερη λύση σχετικά με το πρόβλημά σας.';
out.main_drive = 'CryptDrive';
out.main_richTextPad = 'Pad εμπλουτισμένου κειμένου';
out.main_codePad = 'Pad κώδικα';
out.main_slidePad = 'Markdown παρουσίαση';
out.main_pollPad = 'Δημοσκόπηση ή Χρονοδιάγραμμα';
out.main_whiteboardPad = 'Πίνακας σχεδιασμού';
out.main_localPads = 'Τοπικά pads';
out.main_yourCryptDrive = 'Το CryptDrive σας';
out.main_footerText = "Με το CryptPad, μπορείτε να δημιουργήσετε γρήγορα συνεργατικά έγγραφα για κοινόχρηστες σημειώσεις και καταγραφή ιδεών.";
out.footer_applications = "Εφαρμογές";
out.footer_contact = "Επικοινωνία";
out.footer_aboutUs = "Σχετικά με εμάς";
out.about = "Σχετικά";
out.privacy = "Ιδιωτικότητα";
out.contact = "Επικοινωνία";
out.terms = "Όροι χρήσης";
out.blog = "Ιστολόγιο";
out.topbar_whatIsCryptpad = "Τι είναι το CryptPad";
// what-is-cryptpad.html
out.whatis_title = 'Τι είναι το CryptPad';
out.whatis_collaboration = 'Γρήγορη, εύκολη συνεργασία';
out.whatis_collaboration_p1 = 'Με το CryptPad, μπορείτε να δημιουργείτε όλοι μαζί γρήγορα συνεργατικά έγγραφα για τις σημειώσεις σας και τις ιδέες που καταγράφετε. Όταν εγγραφείτε και συνδεθείτε, σας δίνεται άμεσα η δυνατότητα \'ανεβάσματος\' κι έναν \'αποθηκευτικό χώρο\' CryptDrive όπου μπορείτε να οργανώσετε όλα σας τα pads. Ως εγγεγραμένος χρήστης παίρνετε 50MB δωρεάν.';
out.whatis_collaboration_p2 = 'Μπορείτε να μοιραστείτε την πρόσβαση σε ένα έγγραφο του CryptPad απλά δίνοντας τον σύνδεσμο σε κάποιον άλλο. Μπορείτε επίσης να μοιραστείτε ένα σύνδεσμο ο οποίος παρέχει πρόσβαση <em>μόνο για ανάγνωση</em> σε ένα pad, επιτρέποντάς σας να κοινοποιήσετε την συλλογική σας δουλειά ενώ ταυτόχρονα έχετε ακόμα τη δυνατότητα να το επεξεργαστείτε.';
out.whatis_collaboration_p3 = 'Μπορείτε να δημιουργήσετε απλά εμπλουτισμένα κείμενα με το <a href="http://ckeditor.com/">CKEditor</a> όπως επίσης κείμενα με γλώσσα προγραμματισμού Markdown τα οποία τροποποιούνται σε πραγματικό χρόνο καθώς πληκτρολογείτε. Μπορείτε επίσης να χρησιμοποιήσετε την εφαρμογή δημοσκόπησης για να προγραμματίσετε δραστηριότητες με πολλαπλούς συμμετέχοντες.';
out.whatis_zeroknowledge = 'Zero Knowledge';
out.whatis_zeroknowledge_p1 = "Δεν θέλουμε να ξέρουμε τι πληκτρολογείτε και με τον σύγχρονο τρόπο κρυπτογράφησης μπορείτε να είσαστε σίγουροι ότι δεν μπορούμε να ξέρουμε. Το CryptPad χρησιμοποιεί <strong>100% κρυπτογράφηση client side</strong> για να προστατεύσει το περιεχόμενο που πληκτρολογείτε από εμάς, τους ανθρώπους που φιλοξενούν τον διακομιστή.";
out.whatis_zeroknowledge_p2 = 'Όταν κάνετε εγγραφή και συνδέεστε, το όνομα χρήστη σας κι ο κωδικός σας μετατρέπονται σε ένα κρυπτογραφημένο κλειδί χρησιμοποιώντας το <a href="https://en.wikipedia.org/wiki/Scrypt">scrypt key derivation function</a>. Το συγκεκριμένο κλειδί, το όνομα χρήστη κι ο κωδικός χρήστη δεν στέλνονται καν στον διακομιστή. Αντιθέτως χρησιμοποιούνται από το client side για να αποκρυπτογραφήσουν το περιεχόμενο του CryptDrive σας, το οποίο περιέχει όλα τα κλειδιά για όλα τα pads στα οποία μπορείτε να έχετε πρόσβαση.';
out.whatis_zeroknowledge_p3 = 'Όταν μοιράζεστε έναν σύνδεσμο προς ένα έγγραφο, μοιράζεστε το κρυπτογραφημένο κλειδί για το συγκεκριμένο έγγραφο αλλά εφόσον το κλειδί είναι στο <a href="https://en.wikipedia.org/wiki/Fragment_identifier">fragment identifier</a>, δεν στέλνεται ποτέ απευθείας στον διακομιστή. Επισκεφθείτε το <a href="https://blog.cryptpad.fr/2017/07/07/cryptpad-analytics-what-we-cant-know-what-we-must-know-what-we-want-to-know/">privacy blog post</a> για να μάθετε περισσότερα σχετικά με το σε ποια μεταδεδομένα έχουμε πρόσβαση και σε ποια όχι.';
out.whatis_drive = 'Οργάνωση με το CryptDrive';
out.whatis_drive_p1 = 'Κάθε φορά που επισκέπτεσθε ένα pad στο CryptPad, το pad προστίθεται αυτόματα στο CryptDrive στον κυρίως φάκελο. Αργότερα μπορείτε να οργανώσετε αυτά τα pad σε φακέλους ή μπορείτε να τα μετακινήσετε στον κάδο ανακύκλωσης. Το CryptDrive σας επιτρέπει να περιηγηθείτε ανάμεσα στα pads σας και να τα οργανώνετε όποτε κι όπως θέλετε.';
out.whatis_drive_p2 = 'Με το κλασικό drag-and-drop, μπορείτε να μεταφέρετε pads μέσα στον αποθηκευτικό σας χώρο και ο σύνδεσμος αυτών των pads θα παραμείνει ο ίδιος ώστε οι συνεργάτες σας να μην σταματήσουν ποτέ να έχουν πρόσβαση.';
out.whatis_drive_p3 = 'Μπορείτε επίσης να ανεβάσετε αρχεία στο CryptDrive σας και να τα μοιραστείτε με συνεργάτες. Τα ανεβασμένα αρχεία μπορούν να οργανωθούν ακριβώς όπως τα συνεργατικά pads.';
out.whatis_business = 'Το CryptPad για επιχειρήσεις';
out.whatis_business_p1 = 'Το πρωτόκολλο κρυπτογράφησης Zero Knowledge του CryptPad είναι ιδανικό για να πολλαπλασιαστεί η αποτελεσματικότητα των ήδη υπάρχοντων πρωτοκόλλων ασφαλείας προστατεύοντας τα εταιρικά στοιχεία πρόσβασης με ισχυρή κρυπτογράφηση. Επειδή τα ευαίσθητα δεδομένα μπορούν να αποκρυπτογραφηθούν μόνο με την χρήση των στοιχείων των υπαλλήλων, το CryptPad εξαλείφει τον παράγοντα hacker ο οποίος ενυπάρχει σε παραδοσιακούς εταιρικούς διακομιστές. Διαβάστε το <a href="https://blog.cryptpad.fr/images/CryptPad-Whitepaper-v1.0.pdf">CryptPad Whitepaper</a> για να μάθετε περισσότερα σχετικά με το πως μπορεί να βοηθήσει την επιχείρησή σας.';
out.whatis_business_p2 = 'To CryptPad μπορεί να εγκατασταθεί τοπικά και οι <a href="https://cryptpad.fr/about.html">προγραμματιστές του</a> στην XWiki SAS είναι σε θέση να προσφέρουν εμπορική υποστήριξη, τροποποιήσεις και περαιτέρω ανάπτυξη. Επικοινωνήστε στο <a href="mailto:sales@cryptpad.fr">sales@cryptpad.fr</a> για περισσότερες πληροφορίες.';
// privacy.html
out.policy_title = 'Πολιτική απορρήτου του CryptPad';
out.policy_whatweknow = 'Τι γνωρίζουμε για εσάς';
out.policy_whatweknow_p1 = 'Ως εφαρμογή η οποία φιλοξενείται στο διαδίκτυο, το CryptPad έχει πρόσβαση στα μεταδεδομένα που είναι εκτεθειμένα από το πρωτόκολλο HTTP. Αυτό συμπεριλαμβάνει την διεύθυνση IP σας και ποικίλες HTTP κεφαλίδες που μπορούν να χρησιμοποιηθούν για να ταυτοποιήσουν τον συγκεκριμένο περιηγητή. Μπορείτε να δείτε τι πληροφορίες μοιράζεται ο περιηγητής σας με το να επισκεφθείτε <a target="_blank" rel="noopener noreferrer" href="https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending" title="what http headers is my browser sending">WhatIsMyBrowser.com</a>.';
out.policy_whatweknow_p2 = 'Χρησιμοποιούμε το <a href="https://www.elastic.co/products/kibana" target="_blank" rel="noopener noreferrer" title="open source analytics platform">Kibana</a>, μια πλατφόρμα ανάλυσης ανοιχτού κώδικα, για να μάθουμε περισσότερα για τους χρήστες μας. Το Κibana μας ενημερώνει για το πως βρήκατε το CryptPad, μέσω απευθείας σύνδεσης, μέσω μηχανής αναζήτησης, ή μέσω αναφοράς από άλλη διαδυκτιακή υπηρεσία όπως το Reddit ή το Twitter.';
out.policy_howweuse = 'Πώς χρησιμοποιούμε αυτά που μαθαίνουμε';
out.policy_howweuse_p1 = 'Χρησιμοποιούμε αυτές τις πληροφορίες για να παίρνουμε καλύτερες αποφάσεις σχετικά με την προώθηση του CryptPad, εξετάζοντας ποιες από τις προηγούμενες προσπάθειές μας υπήρξαν επιτυχείς. Οι πληροφορίες σχετικά με την τοποθεσία σας μας βοηθούν στο να σκεφτούμε αν θα έπρεπε να παρέχουμε καλύτερη υποστήριξη για γλώσσες εκτός των Αγγλικών.';
out.policy_howweuse_p2 = "Οι πληροφορίες σχετικά με τον περιηγητή σας (είτε είναι επιτραπέζιου είτε φορητού λειτουργικού συστήματος) μας βοηθάνε να παίρνουμε αποφάσεις στο θέμα προτεραιοτήτων βελτίωσης χαρακτηριστικών. Η ομάδα προγραμματισμού μας είναι μικρή και προσπαθούμε να κάνουμε επιλογές οι οποίες θα βελτιώσουν την εμπειρία όσων το δυνατό περισσότερων χρηστών.";
out.policy_whatwetell = 'Τι λέμε σε άλλους για εσάς';
out.policy_whatwetell_p1 = 'Δεν παρέχουμε σε τρίτους τις πληροφορίες που συλλέγουμε ή τις πληροφορίες που μας δίνετε εκτός κι αν είμαστε υποχρεωμένοι νομικά.';
out.policy_links = 'Σύνδεσμοι σε άλλες σελίδες';
out.policy_links_p1 = 'Αυτή η ιστοσελίδα περιέχει συνδέσμους προς άλλες σελίδες, συμπεριλαμβανομένων αυτών που δημιουργήθηκαν από άλλους οργανισμούς. Δεν είμαστε υπεύθυνοι για την πολιτική απορρήτου ή το περιεχόμενο μιας εξωτερικής σελίδας. Ως γενικό κανόνα έχουμε πως οι σύνδεσμοι σε διαφορετικές σελίδες ανοίγουν σε καινούριο παράθυρο για να είναι ξεκάθαρο ότι φεύγετε από το CryptPad.fr.';
out.policy_ads_p1 = 'Δεν προβάλουμε διαφημίσεις εντός της υπηρεσίας, όμως μπορεί να παρέχουμε συνδέσμους στους ανθρώπους που ενισχύουν οικονομικά την έρευνά μας.';
out.policy_choices = 'Οι επιλογές που έχετε';
out.policy_choices_open = 'Ο κώδικάς μας διατίθεται ελεύθερα, οπότε έχετε πάντα την επιλογή να φιλοξενήσετε το Cryptpad σε δικό σας διακομιστή.';
out.policy_choices_vpn = 'Εάν θέλετε να χρησιμοποιήσετε τη δική μας εκδοχή του Cryptpad, αλλά δεν θέλετε να φαίνεται η IP διεύθυνσή σας, μπορείτε να προστατέψετε την IP σας χρησιμοποιώντας το <a href="https://www.torproject.org/projects/torbrowser.html.en" title="downloads from the Tor project" target="_blank" rel="noopener noreferrer">Tor browser bundle</a>, ή ένα <a href="https://riseup.net/en/vpn" title="VPNs provided by Riseup" target="_blank" rel="noopener noreferrer">VPN</a>.';
out.policy_choices_ads = 'Εάν θα θέλατε απλά να εμποδίσετε την πλατφόρμα ανάλυσής μας, μπορείτε να χρησιμοποιήσετε εργαλεία απόκρυψης διαφημίσεων όπως το <a href="https://www.eff.org/privacybadger" title="download privacy badger" target="_blank" rel="noopener noreferrer">Privacy Badger</a>.';
// terms.html
out.tos_title = " Όροι και Προϋποθέσεις του CryptPad";
out.tos_legal = "Παρακαλούμε μην κάνετε κακή χρήση ή/και κατάχρηση της υπηρεσίας ή οτιδήποτε παράνομο.";
out.tos_availability = "Ελπίζουμε να βρείτε χρήσιμη αυτή την υπηρεσία, αλλά η προσβασιμότητα κι η απόδοση δεν μπορούν να εγγυηθούν. Παρακαλούμε κάνετε εξαγωγή των δεδομένων σας συχνά.";
out.tos_e2ee = "Τα περιεχόμενα του CryptPad μπορούν να διαβαστούν ή να αλλαχθούν από οποιονδήποτε μπορεί να μαντέψει ή να αποκτήσει την ηλεκτρονική διεύθυνση του pad. Προτείνουμε να χρησιμοποιείτε τεχνολογία κρυπτογραφημένων μηνυμάτων από άκρη σε άκρη (e2ee) για να μοιράζεστε συνδέσμους και να μην αναλάβετε καμία ευθύνη σε περίπτωση που διαρρέυσει κάποιος τέτοιος σύνδεσμος.";
out.tos_logs = "Τα μεταδεδομένα που παρέχονται από τον περιηγητή σας στον διακομιστή μπορεί να καταγράφονται με σκοπό τη συντήρηση της υπηρεσίας.";
out.tos_3rdparties = "Δεν παρέχουμε προσωπικά δεδομένα σε τρίτους παρά μόνο εάν ζητηθεί από το νόμο.";
// 404 page
out.four04_pageNotFound = "Η σελίδα που ψάχνετε, δεν βρέθηκε!";
// BottomBar.html
//out.bottom_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Δημιουργήθηκε με <img class="bottom-bar-heart" src="/customize/heart.png" alt="love" /> στην <img class="bottom-bar-fr" src="/customize/fr.png" alt="Γαλλία" /></a>';
//out.bottom_support = '<a href="http://labs.xwiki.com/" title="XWiki Labs" target="_blank" rel="noopener noreferrer">Ένα <img src="/customize/logo-xwiki2.png" alt="XWiki SAS" class="bottom-bar-xwiki"/> Labs Project </a> με την υποστήριξη του <a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
// Header.html
out.header_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Με <img class="bottom-bar-heart" src="/customize/heart.png" alt="love" /> στην <img class="bottom-bar-fr" src="/customize/fr.png" title="Γαλλία" alt="Γαλλία"/> από την <img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
out.header_support = '<a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
out.updated_0_header_logoTitle = 'Μετάβαση στο CryptDrive σας';
out.header_logoTitle = out.updated_0_header_logoTitle;
out.header_homeTitle = 'Μετάβαση στην αρχική σελίδα του CryptPad';
// Initial states
out.initialState = [
'<p>',
'Αυτό είναι&nbsp;<strong>CryptPad</strong>, ο συνεργατικός επεξεργαστής πραγματικού χρόνου Zero Knowledge. Τα πάντα αποθηκεύονται καθώς πληκτρολογείτε.',
'<br>',
'Μοιραστείτε τον σύνδεσμο σε αυτό το pad για να το επεξεργαστείτε με φίλους ή χρησιμοποιήστε το κουμπί <span class="fa fa-share-alt"></span> για να μοιραστείτε ένα κείμενο με δικαιώματα <em>read-only link</em>&nbsp;το οποίο επιτρέπει να το αναγνώσει κάποιος αλλά όχι να το επεξεργαστεί.',
'</p>',
].join('');
out.codeInitialState = [
'# Ο συνεργατικός επεξεργαστής Zero Knowledge του CryptPad\n',
'\n',
'* Ό,τι πληκτρολογείτε εδώ είναι κρυπτογραφημένο έτσι ώστε μόνο οι άνθρωποι που έχουν τον σύνδεσμο να μπορούν να έχουν πρόσβαση.\n',
'* Μπορείτε να επιλέξετε την γλώσσα προγραμματισμού για να υπογραμμίζετε και το χρώμα του θέματος UI πάνω δεξιά.'
].join('');
out.slideInitialState = [
'# CryptSlide\n',
'1. Γράψτε τα περιεχόμενα των slides σας χρησιμοποιώντας σύνταξη markdown\n',
' - Μάθετε περισσότερα για την σύνταξη markdown [εδώ](http://www.markdowntutorial.com/)\n',
'2. Διαχωρίστε τα slides σας με ---\n',
'3. Πατήστε το κουμπάκι "Play" για να δείτε το αποτέλεσμα',
' - Τα slides σας ενημερώνονται σε πραγματικό χρόνο'
].join('');
// Readme
out.driveReadmeTitle = "Τι είναι το CryptPad;";
out.readme_welcome = "Καλωσήρθατε στο CryptPad!";
out.readme_p1 = "Καλωσήρθατε στο CryptPad, όπου μπορείτε να έχετε τις σημειώσεις σας μόνοι σας ή με φίλους.";
out.readme_p2 = "Αυτό το pad έχει έναν γρήγορο οδηγό χρήσης του πως να χρησιμοποιήσετε το CryptPad για να κρατάτε σημειώσεις, να τις έχετε οργανωμένες και να δουλέψετε πάνω τους συνεργατικά.";
out.readme_cat1 = "Μάθετε το CryptDrive σας";
out.readme_cat1_l1 = "Δημιούργηστε ένα pad: Στο CryptDrive σας, κάντε \"κλικ\" στο {0} και έπειτα στο {1} και μπορείτε να δημιουργήσετε ένα pad."; // 0: New, 1: Rich Text
out.readme_cat1_l2 = "Ανοίξτε pads από το CryptDrive σας: κάντε διπλό \"κλικ\" σε ένα εικονίδιο pad για να το ανοίξετε.";
out.readme_cat1_l3 = "Οργάνωστε τα pads σας: Όταν είσαστε συνδεδεμένοι, κάθε pad στο οποίο έχετε πρόσβαση θα εμφανίζεται ως {0} στο τμήμα του δίσκου σας."; // 0: Unsorted files
out.readme_cat1_l3_l1 = "Μπορείτε να κάνετε \"κλικ\" και να σύρετε αρχεία μέσα σε φακέλους στον τομέα {0} του δίσκου σας και να δημιουργήσετε καινούρια αρχεία."; // 0: Documents
out.readme_cat1_l3_l2 = "Θυμηθείτε να δοκιμάζετε το δεξί \"κλικ\" στα εικονίδια διότι συχνά υπάρχουν επιπρόσθετα μενού.";
out.readme_cat1_l4 = "Πετάξτε τα παλιά pads στα σκουπίδια: Μπορείτε να κάνετε \"κλικ\" και να σύρετε τα pads μέσα στα {0} με τον ίδιο τρόπο που τα σύρετε μέσα στους φακέλους."; // 0: Trash
out.readme_cat2 = "Δημιουργείστε pads σαν επαγγελματίας";
out.edit = "επεξεργασία";
out.view = "προβολή";
out.readme_cat2_l1 = "Το κουμπί {0} στο pad σας επιτρέπει να δίνετε πρόσβαση στους συνεργάτες σας είτε να κάνουν {1} είτε να κάνουν {2} το pad."; // 0: Share, 1: edit, 2: view
out.readme_cat2_l2 = "Αλλάξτε τον τίτλο του pad κάνοντας \"κλικ\" στο μολύβι";
out.readme_cat3 = "Ανακαλύψτε CryptPad εφαρμογές";
out.readme_cat3_l1 = "Με το CryptPad code editor, μπορείτε να συνεργαστείτε σε κώδικα όπως οι γλώσσες προγραμματισμού Javascript και markdown ή HTML και Markdown";
out.readme_cat3_l2 = "Με το CryptPad slide editor, μπορείτε να κάνετε γρήγορες παρουσιάσεις χρησιμοποιώντας γλώσσα Markdown";
out.readme_cat3_l3 = "Με το CryptPoll μπορείτε να ψηφίζετε γρήγορα, ειδικά για να ορίζετε συναντήσεις σε ημερομηνίες που ταιριάζουν με το πρόγραμμα όλων";
// Tips
out.tips = {};
out.tips.shortcuts = "`ctrl+b`, `ctrl+i` και `ctrl+u` είναι γρήγορες συντομεύσεις για έντονα, πλάγια και υπογραμμισμένα γράμματα.";
out.tips.indent = "Σε αριθμημένες λίστες όπως και λίστες με τελείες, μπορείτε να χρησιμοποιήσετε tab ή shift+tab για να αυξήσετε ή να μειώσετε τις εσοχές με γρήγορο τρόπο.";
out.tips.store = "Κάθε φορά που επισκέπτεστε ένα pad, εάν είσαστε συνδεδεμένοι, θα σώζεται αυτόματα στο CryptDrive σας.";
out.tips.marker = "Μπορείτε να υπογραμμίσετε κείμενο σε ένα pad χρησιμοποιώντας τον \"μαρκαδόρο\" από το μενού μορφoποίησης.";
out.tips.driveUpload = "Οι εγγεγραμένοι χρήστες μπορούν να ανεβάσουν κρυπτογραφημένα αρχεία σύροντάς τα και πετώντας τα στο CryptDrive τους.";
out.tips.filenames = "Μπορείτε να μετονομάσετε αρχεία στο CryptDrive σας. Το όνομα που θα δώσετε είναι μόνο για εσάς.";
out.tips.drive = "Οι συνδεδεμένοι χρήστες μπορούν να οργανώσουν τα αρχεία τους στο CryptDrive τους, τα οποία είναι προσβάσιμα από το εικονίδιο CryptPad που είναι πάνω αριστερά σε όλα τα pads.";
out.tips.profile = "Οι εγγεγραμένοι χρήστες μπορούν να δημιουργήσουν ένα προφίλ από το μενού χρήστη πάνω δεξιά.";
out.tips.avatars = "Μπορείτε να ανεβάσετε ένα άβαταρ στο προφίλ σας. Θα το βλέπουν οι άλλοι όταν συνεργάζεστε σε ένα pad.";
out.tips.tags = "Βάλτε ετικέτες στα pads σας και ψάξτε με # στο CryptDrive σας για να τα βρείτε";
out.feedback_about = "Εάν το διαβάζετε αυτό, πιθανότατα ήσασταν περίεργοι για ποιο λόγο το CryptPad ζητά ιστοσελίδες όταν κάνετε συγκεκριμένες ενέργειες";
out.feedback_privacy = "Ενδιαφερόμαστε για την ιδιωτικότητά σας και ταυτόχρονα θέλουμε το CryptPad να είναι πολύ εύκολο στην χρήση. Χρησιμοποιούμε αυτό το αρχείο για να καταλάβουμε ποια χαρακτηριστικά του περιβάλλοντος διάδρασης ενδιαφέρουν τους χρήστες μας, με το να το ζητήσουμε σε συνδυασμό με μια παράμετρο η οποία μας δείχνει συγκεκριμένα ποια ενέργεια έγινε.";
out.feedback_optout = "Εάν θα θέλατε να απέχετε, επισκεφθείτε <a href='/settings/'>τη σελίδα ρυθμίσεων</a> του λογαριασμού σας, όπου θα βρείτε ένα κουτί στο οποίο μπορείτε να ενεργοποιήσετε ή να απενεργοποιήσετε την αναπληροφόρηση";
return out;
/*
* You can override the translation text using this file.
* The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js)
in a 'customize' directory (/customize/translations/messages.{LANG}.js).
* If you want to check all the existing translation keys, you can open the internal language file
but you should not change it directly (/common/translations/messages.{LANG}.js)
*/
define(['/common/translations/messages.el.js'], function (Messages) {
// Replace the existing keys in your copied file here:
// Messages.button_newpad = "New Rich Text Document";
return Messages;
});

View File

@ -1,578 +1,14 @@
define(function () {
var out = {};
out._languageName = 'Español';
out.main_title = "Cryptpad: Zero Knowledge, Editor Colaborativo en Tiempo Real";
out.main_slogan = "La unidad es la fuerza - la colaboración es la clave";
out.type = {};
out.type.pad = 'Pad';
out.type.code = 'Código';
out.type.poll = 'Encuesta';
out.type.slide = 'Presentación';
out.type.whiteboard = 'Pizarra';
out.type.contacts = 'Contactos';
out.disconnected = "Desconectado";
out.synchronizing = "Sincronización";
out.reconnecting = "Reconectando...";
out.lag = "Retraso";
out.readonly = 'Sólo lectura';
out.anonymous = 'Anónimo';
out.yourself = "Tú mismo";
out.anonymousUsers = "usuarios anónimos";
out.anonymousUser = "usuario anónimo";
out.users = "Usuarios";
out.and = "y";
out.viewer = "espectador";
out.viewers = "espectadores";
out.editor = "editor";
out.editors = "editores";
out.greenLight = "Todo funciona bien";
out.orangeLight = "La conexión es lenta y podría afectar la experiencia";
out.redLight = "Has sido desconectado de la sesión";
out.importButtonTitle = 'Importar un documento de tus archivos locales';
out.exportButtonTitle = 'Exportar este documento a un archivo local';
out.exportPrompt = '¿Cómo te gustaría llamar a este archivo?';
out.changeNamePrompt = 'Cambiar tu nombre (dejar vacío para ser anónimo): ';
out.clickToEdit = "Haz clic para cambiar";
out.forgetButtonTitle = 'Eliminar este documento de la lista en la pagina de inicio';
out.forgetPrompt = 'Pulsar OK eliminará este documento del almacenamiento local (localStorage), ¿estás seguro?';
out.shareButton = 'Compartir';
out.shareSuccess = 'URL copiada al portapapeles';
out.presentButtonTitle = "Entrar en el modo presentación";
out.backgroundButtonTitle = 'Cambiar el color de fondo en el modo presentación';
out.colorButtonTitle = 'Cambiar el color de texto en el modo presentación';
out.editShare = "URL de edición compartida";
out.editShareTitle = "Copiar la URL de edición al portapapeles";
out.viewShare = "Compartir URL de sólo lectura";
out.viewShareTitle = "Copiar la URL de sólo lectura al portapapeles";
out.viewOpen = "Ver en pestaña nueva";
out.viewOpenTitle = "Abrir el documento en sólo lectura en una pestaña nueva";
out.notifyJoined = "{0} se ha unido a la sesión de colaboración";
out.notifyRenamed = "{0} ahora se conoce como {1}";
out.notifyLeft = "{0} ha dejado la sesión de colaboración";
out.tryIt = '¡Pruébalo!';
out.okButton = 'OK (Enter)';
out.cancelButton = 'Cancelar (Esc)';
// Polls
out.poll_title = "Selector de fecha Zero Knowledge";
out.poll_subtitle = "Agenda en <em>tiempo real</em> Zero Knowledge";
out.poll_p_save = "Tus configuraciones se actualizan instantáneamente, no es necesario guardar cambios.";
out.poll_p_encryption = "Todos los datos entrados son cifrados, sólo las personas que poseen el enlace tienen acceso. Incluso el servidor no puede ver el contenido.";
out.wizardLog = "Presiona el botón en la parte superior izquierda para volver a la encuesta";
out.wizardTitle = "Utiliza el asistente para crear tu encuesta";
out.wizardConfirm = "¿Estás realmente seguro de agregar estas opciones a tu encuesta?";
out.poll_closeWizardButton = "Cerrar el asistente";
out.poll_closeWizardButtonTitle = "Cerrar el asistente";
out.poll_wizardComputeButton = "Generar opciones";
out.poll_wizardClearButton = "Limpiar tabla";
out.poll_wizardDescription = "Crear opciones automáticamente ingresando cualquier cantidad de fechas y horas";
out.poll_wizardAddDateButton = "+ Fechas";
out.poll_wizardAddTimeButton = "+ Horas";
out.poll_optionPlaceholder = "Opción";
out.poll_userPlaceholder = "Tu nombre";
out.poll_removeOption = "¿Estás seguro de que quieres eliminar esta opción?";
out.poll_removeUser = "¿Estás seguro de que quieres eliminar este usuario?";
out.poll_titleHint = "Título";
out.poll_descriptionHint = "Descripción";
// index.html
out.main_p2 = 'Este proyecto utiliza el editor de texto visual <a href="http://ckeditor.com/">CKEditor</a>, <a href="https://codemirror.net/">CodeMirror</a>, y el motor en tiempo real <a href="https://github.com/xwiki-contrib/chainpad">ChainPad</a>.';
out.main_howitworks = '¿Cómo funciona?';
out.main_howitworks_p1 = "CryptPad utiliza una variante del algoritmo de <a href='https://en.wikipedia.org/wiki/Operational_transformation'>transformación operacional</a> (página en inglés) que es capaz de encontrar un consenso distribuido usando un <a href='https://bitcoin.org/bitcoin.pdf'>Blockchain Nakamoto</a> (página en inglés), popularizado por <a href='https://es.wikipedia.org/wiki/Bitcoin'>Bitcoin</a>. De esta manera el algoritmo puede evitar la necesidad de un servidor central para resolver conflictos de edición de la transformación operacional y sin necesidad de resolver conflictos, el servidor puede mantenerse inconsciente del contenido que se está editando en el pad.";
out.main_about_p2 = 'Si tienes preguntas o comentarios, puedes <a href="https://twitter.com/cryptpad"><i class="fa fa-twitter"></i>enviarnos un tweet</a>, abrir un issue <a href="https://github.com/xwiki-labs/cryptpad/issues/" title="nuestro issue tracker">en <i class="fa fa-github"></i>GitHub</a>. saludarnos en <a href="https://riot.im/app/#/room/#cryptpad:matrix.org" title="Matrix">nuestro <i class="fa fa-comment"></i>canal Matrix</a> o en IRC (#cryptpad on irc.freenode.net), o <a href="mailto:research@xwiki.com"><i class="fa fa-envelope"></i>envianos un email</a>.';
out.button_newpad = 'Crear nuevo pad de texto enriquecido';
out.button_newcode = 'Crear nuevo pad de código';
out.button_newpoll = 'Crear nueva encuesta';
out.button_newslide = 'Crear nueva presentación';
// privacy.html
out.policy_title = 'Política de privacidad Cryptpad';
out.policy_whatweknow = 'Qué sabemos sobre tí';
out.policy_whatweknow_p1 = 'Como cualquier aplicación que está en la red, Cryptpad tiene acceso a los metadatos expuestos por el protocolo HTTP. Esto incluye tu dirección IP, y otros headers HTTP que pueden ser utilizados para identificar a tu navegador propio. Puedes ver la información que comparte tu navegador visitando <a target="_blank" rel="noopener noreferrer" href="https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending" title="Qué headers HTTP esta compartiendo mi navegador">WhatIsMyBrowser.com</a> (página en inglés).';
out.policy_whatweknow_p2 = 'Nosotros usamos <a href="https://piwik.org/" target="_blank" rel="noopener noreferrer" title="open source analytics platform">Piwik</a>, una plataforma de analítica de datos abierta, para conocer mejor a nuestros usuarios. Piwik nos dice como encontraste Cryptpad, en entrada manual, por un motor de búsqueda, or por referal de otra página como Reddit o Twitter. También aprendemos cuándo visitas, qué páginas ves en nuestra web, y cuánto tiempo te quedas en cada una.';
out.policy_howweuse = 'Cómo usamos lo que aprendemos';
out.policy_howweuse_p1 = 'Usamos esta información para tomar mejores decisiones para promocionar Cryptpad, para evaluar cuáles de nuestros esfuerzos han sido exitosos. La información sobre tu ubicación nos permite saber si deberíamos considerar mejor soporte para idiomas diferentes al inglés.';
out.policy_howweuse_p2 = "La información sobre tu navegador (en escritorio o móvil) nos ayuda a saber qué características que debemos mejorar. Nuestro equipo de desarrollo es pequeño, e intentamos tomar decisiones que beneficien a la experiencia de la mayoría de nuestros usuarios.";
out.policy_whatwetell = 'Lo que decimos a otros sobre tí';
out.policy_whatwetell_p1 = 'No suministramos la información que recolectamos a terceros a menos de estar legalmente obligados a hacerlo.';
out.policy_links = 'Enlaces a otras páginas';
out.policy_links_p1 = 'Esta web contiene enlaces a otros sitios, incluyendo algunos producidos por otras organizaciones. No somos responsables del tratamiento de la privacidad de los datos ni el contenido de páginas externas. Como regla general, los enlaces externos se abren en una nueva pestaña del navegador, para clarificar que estás abandonando a Cryptpad.fr.';
out.policy_ads = 'Anuncios';
out.policy_ads_p1 = 'Nosotros no mostramos anuncios, pero podemos poner enlaces a las organizaciones que financian nuestro trabajo de investigación.';
out.policy_choices = 'Lo que puedes hacer';
out.policy_choices_open = 'Nuestro código fuente es abierto para que siempre tengas la opción de desplegar tu propia instancia de Cryptpad.';
out.policy_choices_vpn = 'Si deseas utilizar nuestra instancia, pero no deseas exponer tu dirección IP, puedes protegerla utilizando <a href="https://www.torproject.org/projects/torbrowser.html.en" title="descargas Tor project" target="_blank" rel="noopener noreferrer">el navegador Tor</a>, o un <a href="https://riseup.net/en/vpn" title="VPNs por Riseup" target="_blank" rel="noopener noreferrer">VPN</a>.';
out.policy_choices_ads = 'Si deseas no ser seguido por nuestra plataforma, puedes utilizar herramientas como <a href="https://www.eff.org/privacybadger" title="descargar a Privacy Badger" target="_blank" rel="noopener noreferrer">Privacy Badger</a>.';
// terms.html
out.tos_title = "Condiciones de servicio Cryptpad";
out.tos_legal = "Por favor, no seas malicioso, abusivo o hagas algo ilegal.";
out.tos_availability = "Esperamos que este servicio te parezca útil, pero nuestra disponibilidad o rendimiento no pueden ser garantizados. Por favor, exporta tus datos regularmente.";
out.tos_e2ee = "Los documentos Cryptpad pueden ser leídos o modificados por cualquiera que pueda adivinar o que pueda tener el enlace. Recomendamos que utilices mensajes cifrados de punto a punto (e2ee) para compartir URLs, no asumimos ninguna responsabilidad en el evento de alguna fuga.";
out.tos_logs = "Los metadatos entregados por el navegador al servidor pueden ser almacenados para la mantenencia del servicio.";
out.tos_3rdparties = "No proveemos datos individualizados a terceros a menos de ser obligados por la ley.";
// BottomBar.html
out.bottom_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Hecho con <img class="bottom-bar-heart" src="/customize/heart.png" alt="amor" /> en <img class="bottom-bar-fr" src="/customize/fr.png" alt="Francia" /></a>';
out.bottom_support = '<a href="http://labs.xwiki.com/" title="XWiki Labs" target="_blank" rel="noopener noreferrer">Un <img src="/customize/logo-xwiki2.png" alt="XWiki SAS" class="bottom-bar-xwiki"/>Proyecto Labs</a> con el soporte de <a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"><img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
// Header.html
out.header_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Con <img class="bottom-bar-heart" src="/customize/heart.png" alt="amor" /> de <img class="bottom-bar-fr" src="/customize/fr.png" title="France" alt="Francia"/> por <img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
out.header_support = '<a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferre-r"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
out.header_logoTitle = 'Ir a la página principal';
out.websocketError = "Error al conectarse al servidor WebSocket";
out.typeError = "Este documento no es compatible con la aplicación seleccionada";
out.onLogout = "Tu sesión está cerrada, {0}haz clic aquí{1} para iniciar sesión<br>o pulsa <em>Escape</em> para acceder al documento en modo sólo lectura.";
out.loading = "Cargando...";
out.error = "Error";
out.language = "Idioma";
out.user_rename = "Cambiar nombre";
out.user_displayName = "Nombre visible";
out.user_accountName = "Nombre de cuenta";
out.newButton = "Nuevo";
out.newButtonTitle = "Nuevo documento";
out.cancel = "Cancelar";
out.poll_publish_button = "Publicar";
out.poll_admin_button = "Administrar";
out.poll_create_user = "Añadir usuario";
out.poll_create_option = "Añadir opción";
out.poll_commit = "Validar";
out.fm_rootName = "Documentos";
out.fm_trashName = "Papelera";
out.fm_unsortedName = "Sin organizar";
out.fm_filesDataName = "Todos los archivos";
out.fm_templateName = "Plantilla";
out.fm_newButton = "Nuevo";
out.fm_newFolder = "Nueva carpeta";
out.fm_folder = "Carpeta";
out.fm_folderName = "Nombre de carpeta";
out.fm_numberOfFolders = "# de carpetas";
out.fm_numberOfFiles = "# de archivos";
out.fm_fileName = "Nombre";
out.fm_title = "Título";
out.fm_lastAccess = "Último acceso";
out.fm_creation = "Creación";
out.fm_forbidden = "Acción prohibida";
out.fm_originalPath = "Enlace original";
out.fm_noname = "Documento sin título";
out.fm_emptyTrashDialog = "¿Seguro que quieres vaciar la papelera?";
out.fm_removeSeveralPermanentlyDialog = "¿Seguro que quieres eliminar estos {0} elementos de la papelera para siempre?";
out.fm_removePermanentlyDialog = "¿Seguro que quieres eliminar este elemento para siempre?";
out.fm_removeSeveralDialog = "¿Seguro que quieres mover estos {0} elementos a la papelera?";
out.fm_removeDialog = "¿Seguro que quieres mover {0} a la papelera?";
out.fm_restoreDialog = "¿Seguro que quieres recuperar {0}?";
out.fm_unknownFolderError = "La carpeta seleccionada ya no existe. Abriendo la carpeta anterior...";
out.fm_contextMenuError = "No se pudo abrir el menú para este elemento. Si persiste el problema, recarga la página.";
out.fm_selectError = "No se pudo abrir el elemento. Si persiste el problema, recarga la página.";
out.fm_info_root = "Crea carpetas aquí para organizar tus documentos.";
out.fm_info_unsorted = "Contiene todos los documentos que has visitado que no están organizados en \"Documentos\" o movidos a la \"Papelera\".";
out.fm_info_template = "Contiene todas las plantillas que puedes volver a usar para crear nuevos documentos.";
out.fm_info_allFiles = "Contiene todos los archivos de \"Documentos\", \"Sin organizar\" y \"Papelera\". No puedes mover o eliminar archivos aquí.";
out.fm_alert_backupUrl = "Enlace de copia de seguridad para este drive. Te recomendamos <strong>encarecidamente</strong> que lo guardes secreto.<br>Lo puedes usar para recuperar todos tus archivos en el caso que la memoria de tu navegador se borre.<br>Cualquiera con este enlace puede editar o eliminar todos los archivos en el explorador.<br>";
out.fm_backup_title = "Enlace de copia de seguridad";
out.fm_nameFile = "¿Cómo quieres nombrar este archivo?";
out.fc_newfolder = "Nueva carpeta";
out.fc_rename = "Cambiar nombre";
out.fc_open = "Abrir";
out.fc_open_ro = "Abrir (sólo lectura)";
out.fc_delete = "Eliminar";
out.fc_restore = "Recuperar";
out.fc_remove = "Eliminar para siempre";
out.fc_empty = "Vaciar la papelera";
out.fc_prop = "Propiedades";
out.fo_moveUnsortedError = "No puedes mover una carpeta en la lista de documentos no organizados";
out.fo_existingNameError = "Nombre ya utilizado en esta carpeta. Por favor elige otro.";
out.fo_moveFolderToChildError = "No puedes mover una carpeta en una de sus subcarpetas";
out.fo_unableToRestore = "No se pudo restaurar este archivo a la localización de origen. Puedes intentar moverlo a otra localización.";
out.fo_unavailableName = "Un archivo o carpeta ya tiene este nombre. Cámbialo y vuelve a intentarlo.";
out.login_login = "Iniciar sesión";
out.login_makeAPad = "Crear documento anónimo";
out.login_nologin = "Ver documentos locales";
out.login_register = "Registrarse";
out.logoutButton = "Cerrar sesión";
out.settingsButton = "Preferencias";
out.login_username = "Nombre de usuario";
out.login_password = "Contraseña";
out.login_confirm = "Confirmar contraseña";
out.login_remember = "Recuérdame";
out.login_hashing = "Generando hash de tu contraseña, esto puede tardar un poco.";
out.login_hello = "Hola {0},";
out.login_helloNoName = "Hola,";
out.login_accessDrive = "Acceder a tu drive";
out.login_orNoLogin = "o";
out.login_noSuchUser = "Credenciales inválidos. Inténtalo de nuevo, o regístrate";
out.login_invalUser = "Nombre de usuario requerido";
out.login_invalPass = "Contraseña requerida";
out.login_unhandledError = "Ha ocurrido un error inesperado :(";
out.register_importRecent = "Importe el historial de tu sesión anónima";
out.register_acceptTerms = "Acepto los <a href='/terms.html' tabindex='-1'>términos de servicio</a>";
out.register_passwordsDontMatch = "Las contraseñas no corresponden";
out.register_mustAcceptTerms = "Tienes que aceptar los términos de servicio";
out.register_mustRememberPass = "No podemos reiniciar tu contraseña si la olvidas. ¡Es muy importante que la recuerdes! Marca la casilla para confirmarlo.";
out.register_header = "Bienvenido a CryptPad";
out.register_explanation = ["<p>Vamos a ver algunas cosas antes</p>", "<ul>", "<li>Tu contraseña es tu clave secreta que cifra todos tus documentos. Si la pierdes no podremos recuperar tus datos.</li>", "<li>Puedes importar documentos que has visto recientemente en tu navegador para tenerlos en tu cuenta.</li>", "<li>Si estás usando un ordenador compartido, tienes que cerrar sesión cuando terminas, cerrar la pestaña no es suficiente.</li>", "</ul>"].join('');
out.settings_title = "Preferencias";
out.settings_save = "Guardar";
out.settings_backupTitle = "Copia de seguridad";
out.settings_backup = "Copia de seguridad";
out.settings_restore = "Recuperar datos";
out.settings_reset = "Quita todos los documentos de tu CryptDrive";
out.settings_resetPrompt = "Esta acción eliminará todos tus documentos.<br>¿Seguro que quieres continuar?<br>Introduce “<em>I love CryptPad</em>” para confirmar.";
out.settings_resetDone = "¡Tu drive ahora está vacio!";
out.settings_resetTips = "Consejos en CryptDrive";
out.settings_resetTipsButton = "Restaurar consejos";
out.settings_resetTipsDone = "Todos los consejos ahora están visibles";
out.main_info = "<h1>Colabora con Confianza</h1><br>Cultiva ideas juntos con documentos compartidos con tecnología <strong>Zero Knowledge</strong> que protege tu privacidad.";
out.main_zeroKnowledge = "Zero Knowledge";
out.main_zeroKnowledge_p = "No tienes que confiar en que <em>no</em> veremos tus documentos, con la tecnología Zero Knowledge de CryptPad <em>no podemos</em>. Aprende más sobre cómo protegemos tu <a href=\"/privacy.html\" title='Privacidad'>Privacidad y Seguridad</a>.";
out.main_writeItDown = "Escríbelo";
out.main_writeItDown_p = "Los mejores proyectos vienen de las más pequeñas ideas. Escribe tus momentos de inspiración e ideas inesperadas porque nunca sabrás cuál será tu próximo descubrimiento.";
out.main_share = "Comparte el enlace, comparte el pad";
out.main_share_p = "Cultiva ideas juntos: ten reuniones eficaces, colabora en listas y haz presentaciones rápidas en todos tus dispositivos.";
out.main_organize = "Organízate";
out.main_organize_p = "Con CryptPad Drive, mantén tu atención en lo más importante. Las carpetas te permiten organizar tus proyectos y tener una visión global de dónde van las cosas.";
out.main_richText = "Editor de Texto Enriquecido";
out.main_richText_p = "Colabora en texto enriquecido con nuestro editor Zero Knowledge en tiempo real <a href=\"http://ckeditor.com\" target=\"_blank\">CkEditor</a>.";
out.main_code = "Editor de código";
out.main_code_p = "Edita código fuente para tus programas con nuestro editor Zero Knowledge en tiempo real <a href=\"https://www.codemirror.net\" target=\"_blank\">CodeMirror</a>.";
out.main_slide = "Editor de presentación";
out.main_slide_p = "Crea presentaciones utilizando Markdown, y visualízalos en tu navegador";
out.main_poll = "Encuestas";
out.main_poll_p = "Planifica tus reuniones y eventos, o vota para la mejor solución a un problema.";
out.main_drive = "CryptDrive";
out.footer_applications = "Aplicaciones";
out.footer_contact = "Contacto";
out.footer_aboutUs = "Acerca de nosotros";
out.about = "Acerca de nosotros";
out.privacy = "Privacidad";
out.contact = "Contacto";
out.terms = "Términos de Servicio";
// 1.1.0 - Bunyip
out.movedToTrash = "Este pad fue movido a la papelera.<br><a href\"/drive/\">Acceder a mi Drive</a>";
out.fm_newFile = "Nuevo pad";
out.fm_type = "Tipo";
out.fm_categoryError = "No se pudo abrir la categoría seleccionada, mostrando la raíz.";
out.settings_userFeedbackHint1 = "CryptPad suministra informaciones muy básicas al servidor, para ayudarnos a mejorar vuestra experiencia.";
out.settings_userFeedbackHint2 = "El contenido de tu pad nunca será compartido con el servidor.";
out.settings_userFeedback = "Activar feedback";
out.settings_anonymous = "No has iniciado sesión. Tus ajustes se aplicarán sólo a este navegador.";
out.blog = "Blog";
out.initialState = [
'<p>',
'Esto es&nbsp;<strong>CryptPad</strong>, el editor colaborativo en tiempo real Zero Knowledge. Todo está guardado cuando escribes.',
'<br>',
'Comparte el enlace a este pad para editar con amigos o utiliza el botón <span class="fa fa-share-alt"></span> para obtener un <em>enlace sólo lectura</em>&nbsp;que permite leer pero no escribir.',
'</p>',
].join('');
out.codeInitialState = "/*\n Esto es CryptPad, el editor colaborativo en tiempo real zero knowledge.\n Lo que escribes aquí está cifrado de manera que sólo las personas con el enlace pueden acceder a ello.\n Incluso el servidor no puede ver lo que escribes.\n Lo que ves aquí, lo que escuchas aquí, cuando sales, se queda aquí\n*/";
out.slideInitialState = "# CryptSlide\n1. Escribe tu contenido en Markdown\n - Puedes aprender más sobre Markdown [aquí](http://www.markdowntutorial.com/)\n2. Separa tus diapositivas con ---\n3. Haz clic en \"Presentar\" para ver el resultado - Tus diapositivas se actualizan en tiempo real";
out.driveReadmeTitle = "¿Qué es CryptPad?";
out.readme_welcome = "¡Bienvenido a CryptPad!";
out.readme_p1 = "Bienvenido a CryptPad, aquí podrás anotar cosas solo o con otra gente.";
out.readme_p2 = "Este pad es una guía rápida para aprender a usar a CryptPad para tomar notas, organizarlas y trabajar con más personas.";
out.readme_cat1 = "Conoce tu CryptDrive";
out.readme_cat1_l1 = "Crea un pad: En CryptDrive, haz clic en {0} y luego en {1} para crear un pad.";
out.readme_cat1_l2 = "Abrir pads desde CryptDrive: haz doble clic en un icono para abrirlo.";
out.readme_cat1_l3 = "Organiza tus pads: Cuando has iniciado sesión, cada pad al que accedes se quedará en tu drive en {0}.";
out.readme_cat1_l3_l1 = "Puedes hacer clic y arrastrar archivos en carpetas desde {0}, y crear nuevas carpetas.";
out.readme_cat1_l3_l2 = "Recuerda hacer clic derecho en los iconos, ya que suele haber menús adicionales.";
out.readme_cat1_l4 = "Elimina tus viejos pads: Haz clic y arrastra tus pads en la {0} de la misma manera que lo harías con carpetas.";
out.readme_cat2 = "Haz pads como un pro";
out.edit = "editar";
out.view = "ver";
out.readme_cat2_l1 = "El botón {0} en tu pad te permite dar acceso a colaboradores para {1} o {2} el pad.";
out.readme_cat2_l2 = "Cambia el título del pad haciendo clic en el lápiz";
out.readme_cat3 = "Descubre las apps CryptPad";
out.readme_cat3_l1 = "Con el editor de código CryptPad, puedes colaborar en código fuente, como por ejemplo JavaScript y Markdown";
out.readme_cat3_l2 = "Con los slides CryptPad, puedes hacer presentaciones rápidas con Markdown";
out.readme_cat3_l3 = "Con CryptPoll puedes hacer una encuesta rápida, especialmente útil para programar un horario que conviene a todo el mundo";
// 1.2.0 - Chupacabra
out.settings_resetError = "Verificación no válida. Tu CryptDrive no fue cambiado.";
out.saved = "Guardado";
out.printButton = "Imprimir";
out.printButtonTitle = "Imprimir tu presentación o exportar a PDF";
out.printOptions = "Opciones de impresión";
out.printSlideNumber = "Mostrar el número de diapositiva";
out.printDate = "Mostrar la fecha";
out.printTitle = "Mostrar el título";
out.printCSS = "CSS personalizado:";
out.editOpen = "Abrir enlaces de edición en pestaña nueva";
out.editOpenTitle = "Abrir en modo edición en pestaña nueva";
out.settings_importTitle = "Importar pads recientes locales en CryptDrive";
out.settings_import = "Importar";
out.settings_importConfirm = "¿Seguro que quieres importar tus pads recientes a tu cuenta CryptDrive?";
out.settings_importDone = "Importación terminada";
out.tips = {};
out.tips.lag = "El icono verde en la parte superior derecha muestra la calidad de tu connexión a CryptPad.";
out.tips.shortcuts = "`ctrl+b`, `ctrl+i`, y `ctrl+u` son accesos rápidos para negrita, itálica y subrayado.";
out.tips.indent = "Cuando editas listas, puedes usar tab o shift+tab para incrementar o decrementar la sangría.";
out.tips.title = "Puedes cambiar el título de tus pads en la parte superior de la pantalla.";
out.tips.store = "Cada vez que visitas un pad con una sesión iniciada se guardará en tu CryptDrive.";
out.tips.marker = "Puedes resaltar texto en un pad utilizando el \"marcador\" en el menú de estílo.";
out.tips.driveUpload = "Los usuarios registrados pueden subir archivos cifrados arrastrándolos hacia CryptDrive.";
out.feedback_about = "Si estas leyendo esto, quizás sientas curiosidad por saber por qué CryptPad solicita páginas cuando realizas algunas acciones";
out.feedback_privacy = "Nos importa tu privacidad, y al mismo tiempo queremos que CryptPad sea muy fácil de usar. Utilizamos este archivo para conocer las funcionalidades que importan a nuestros usuarios, pidiéndolo con un parametro que nos dice qué acción fue realizada.";
out.feedback_optout = "Si quieres darte de baja, visita <a href='/settings/'>tus preferencias</a>, donde podrás activar o desactivar el feedback";
out.fm_searchName = "Buscar";
out.fm_searchPlaceholder = "Buscar...";
out.fm_newButtonTitle = "Crear un nuevo pad o carpeta";
out.fm_openParent = "Mostrar en carpeta";
out.register_writtenPassword = "He escrito mi usuario y contraseña, continuar";
out.register_cancel = "Volver";
out.register_warning = "Zero Knowledge significa que no podemos recuperar tus datos si pierdes tu contraseña.";
out.register_alreadyRegistered = "Este usuario ya existe, ¿iniciar sesión?";
// 1.4.0 - Easter Bunny
out.button_newwhiteboard = "Nueva Pizarra";
out.wrongApp = "No se pudo mostrar el contenido de la sesión en tiempo real en tu navegador. Por favor, actualiza la página.";
out.synced = "Todo está guardado.";
out.saveTemplateButton = "Guardar como plantilla";
out.saveTemplatePrompt = "Elige un título para la plantilla";
out.templateSaved = "¡Plantilla guardada!";
out.selectTemplate = "Elige una plantilla o pulsa ESC";
out.slideOptionsTitle = "Personaliza tus diapositivas";
out.slideOptionsButton = "Guardar (enter)";
out.canvas_clear = "Limpiar";
out.canvas_delete = "Borrar selección";
out.canvas_disable = "No permitir dibujos";
out.canvas_enable = "Permitir dibujos";
out.canvas_width = "Talla";
out.canvas_opacity = "Opacidad";
out.settings_publicSigningKey = "Clave de Firma Pública";
out.settings_usage = "Utilización";
out.settings_usageTitle = "Ve el uso total de tus pads en MB";
out.settings_pinningNotAvailable = "Los pads pegados sólo están disponibles para usuarios registrados.";
out.settings_pinningError = "Algo salió mal";
out.settings_usageAmount = "Tus pads pegados utilizan {0}MB";
out.historyButton = "Mostrar el historial del documento";
out.history_next = "Ir a la versión anterior";
out.history_prev = "Ir a la versión posterior";
out.history_goTo = "Ir a la versión seleccionada";
out.history_close = "Volver";
out.history_closeTitle = "Cerrar el historial";
out.history_restore = "Restaurar";
out.history_restoreTitle = "Restaurar la versión seleccionada del documento";
out.history_restorePrompt = "¿Estás seguro de que quieres cambiar la versión actual del documento por ésta?";
out.history_restoreDone = "Documento restaurado";
out.fc_sizeInKilobytes = "Tamaño en Kilobytes";
// 1.5.0/1.6.0 - Fenrir/Grootslang
out.deleted = "El pad fue borrado de tu CryptDrive";
out.upgrade = "Mejorar";
out.upgradeTitle = "Mejora tu cuenta para obtener más espacio";
out.upgradeAccount = "Mejorar cuenta";
out.MB = "MB";
out.GB = "GB";
out.KB = "KB";
out.formattedMB = "{0} MB";
out.formattedGB = "{0} GB";
out.formattedKB = "{0} KB";
out.pinLimitReached = "Has llegado al límite de espacio";
out.pinLimitNotPinned = "Has llegado al límite de espacio.<br>Este pad no estará presente en tu CryptDrive.";
out.pinLimitDrive = "Has llegado al límite de espacio.<br>No puedes crear nuevos pads.";
out.printTransition = "Activar transiciones";
out.history_version = "Versión: ";
out.settings_logoutEverywhereTitle = "Cerrar sesión en todas partes";
out.settings_logoutEverywhere = "Cerrar todas las otras sesiones";
out.settings_logoutEverywhereConfirm = "¿Estás seguro? Tendrás que volver a iniciar sesión con todos tus dispositivos.";
out.upload_serverError = "Error: no se pudo subir tu archivo en este momento.";
out.upload_uploadPending = "Ya tienes una subida en progreso. ¿Cancelar y subir el nuevo archivo?";
out.upload_success = "Tu archivo ({0}) ha sido subido con éxito y fue añadido a tu drive.";
// 1.7.0 - Hodag
out.comingSoon = "Próximamente...";
out.newVersion = ["<b>CryptPad ha sido actualizado!</b>",
"Puedes ver lo que ha cambiado aquí (en inglés):",
"<a href=\"https://github.com/xwiki-labs/cryptpad/releases/tag/{0}\" target=\"_blank\">Notas de versión para CryptPad {0}</a>"].join("<br>");
out.pinLimitReachedAlertNoAccounts = "Has llegado a tu límite de espacio";
out.previewButtonTitle = "Mostrar/esconder la vista previa Markdown";
out.fm_info_anonymous = "No estás conectado, así que estos pads pueden ser borrados (<a href=\"https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/\" target=\"_blank\">¿por qué?</a>). <a href=\"/register/\">Regístrate</a> o <a href=\"/login/\">Inicia sesión</a> para asegurarlos.";
out.fm_alert_anonymous = "Hola, estás usando CryptPad anónimamente. Está bien, pero tus pads pueden ser borrados después de un périodo de inactividad. Hemos desactivado funciones avanzadas de CryptDrive para usuarios anónimos porque queremos dejar claro que no es un lugar seguro para almacenar cosas. Puedes <a href=\"https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/\" target=\"_blank\">leer este articulo</a> (en inglés) acerca de por qué hacemos esto y por qué deberías <a href=\"/register/\">Registrarte</a> e <a href=\"/login/\">Iniciar sesión</a>.";
out.fm_error_cantPin = "Error del servidor. Por favor, recarga la página e inténtalo de nuevo.";
out.upload_notEnoughSpace = "No tienes suficiente espacio para este archivo en tu CryptDrive";
out.upload_tooLarge = "Este archivo supera el límite de carga.";
out.upload_choose = "Escoge un archivo";
out.upload_pending = "Esperando";
out.upload_cancelled = "Cancelado";
out.upload_name = "Nombre";
out.upload_size = "Tamaño";
out.upload_progress = "Progreso";
out.download_button = "Descifrar y descargar";
out.warn_notPinned = "Este pad no está en ningún CryptDrive. Expirará después de 3 meses. <a href='/about.html#pinning'>Acerca de...</a>";
out.poll_remove = "Quitar";
out.poll_edit = "Editar";
out.poll_locked = "Cerrado";
out.poll_unlocked = "Abierto";
out.poll_show_help_button = "Mostrar ayuda";
out.poll_hide_help_button = "Esconder ayuda";
// 1.8.0 - Idopogo
out.common_connectionLost = "<b>Conexión perdida</b><br>El documento está ahora en modo sólo lectura hasta que la conexión vuelva.";
out.updated_0_common_connectionLost = out.common_connectionLost;
out.supportCryptpad = "Ayudar a CryptPad";
out.pinLimitReachedAlert = ["Has llegado a tu límite de espacio. Los nuevos pads no serán guardados en tu CryptDrive.",
"Puedes eliminar pads de tu CryptDrive o <a href=\"https://accounts.cryptpad.fr/#!on={0}\" target=\"_blank\">suscribirte a una oferta premium</a> para obtener más espacio."].join("<br>");
out.updated_0_pinLimitReachedAlert = out.pinLimitReachedAlert;
out.fm_info_trash = "Vacía tu papelera para liberar espacio en tu CryptDrive.";
out.updated_0_fm_info_trash = out.fm_info_trash;
out.fs_migration = "Tu CryptDrive fue actualizado a una nueva versión.<br><strong>Por favor, recarga la página.</strong>";
out.login_notRegistered = "¿No estás registrado?";
out.upload_mustLogin = "Tienes que estar conectado para subir archivos";
out.uploadButton = "Subir";
out.uploadButtonTitle = "Subir un archivo a la carpeta";
out.filePickerButton = "Incrustar un archivo";
out.filePicker_close = "Cerrar";
out.filePicker_description = "Elige un archivo de tu CryptDrive para incrustarlo o sube uno nuevo";
out.filePicker_filter = "Filtrar por nombre";
out.or = "o";
out.languageButton = "Lenguaje";
out.languageButtonTitle = "Elige el lenguaje para resaltado de sintaxis";
out.themeButton = "Tema";
out.themeButtonTitle = "Selecciona el tema de color para los editores de código y presentación";
out.canvas_opacityLabel = "Opacidad: {0}";
out.canvas_widthLabel = "Talla: {0}";
// 1.10.0 - Kraken
out.moreActions = "Más acciones";
out.importButton = "Importar";
out.exportButton = "Exportar";
out.saveTitle = "Guardar título (enter)";
out.forgetButton = "Eliminar";
out.printText = "Imprimir";
out.slideOptionsText = "Opciones";
out.historyText = "Historial";
out.openLinkInNewTab = "Abrir enlace en pestaña nueva";
out.profileButton = "Perfil";
out.profile_urlPlaceholder = "URL";
out.profile_namePlaceholder = "Nombre mostrado en su perfil";
out.profile_avatar = "Imagen";
out.profile_upload = "Subir una imagen";
out.profile_error = "Error al crear tu perfil: {0}";
out.profile_register = "Tienes que registrarte para crear un perfil";
out.profile_create = "Crear perfil";
out.profile_description = "Descripción";
out.profile_fieldSaved = "Guardado: {0}";
out.download_mt_button = "Descargar";
out.updated_0_header_logoTitle = "Volver a tu CryptDrive";
out.header_logoTitle = out.updated_0_header_logoTitle;
// 1.11.0 - Lutin
out.realtime_unrecoverableError = "El motor de tiempo real ha encontrado un error. Haga clic en OK para recargar la página.";
out.typing = "Escribiendo";
out.profile_inviteButton = "Conectar";
out.profile_inviteButtonTitle = "Crear un enlace de invitación para este usuario.";
out.profile_inviteExplanation = "Hacer clic en <strong>OK</strong> creará un enlace de mensaje seguro que <em>sólo {0} podrá ver.</em><br><br>El enlace será copiado a tu portapapeles y puede ser compartido públicamente.";
out.profile_viewMyProfile = "Ver mi perfil";
out.userlist_addAsFriendTitle = 'Agregar "{0}" como contacto';
out.userlist_thisIsYou = 'Tú mismo ("{0}")';
out.contacts_title = "Contactos";
out.contacts_addError = "Error al agregar este contacto a la lista";
out.contacts_added = "Invitación aceptada";
out.contacts_rejected = "Invitación denegada";
out.contacts_request = "<em>{0}</em> quiere agregarte como contacto. ¿<b>Aceptar</b>?";
out.contacts_send = "Enviar";
out.contacts_remove = "Eliminar este contacto";
out.contacts_confirmRemove = "¿Estás seguro de que quieres eliminar <em>{0}</em> de tus contactos?";
out.contacts_info1 = "Estos son tus contactos. Desde aquí, puedes:";
out.contacts_info2 = "Hacer clic en el icono de tu contacto para chatear";
out.contacts_info3 = "Hacer doble-clic para ver su perfil";
out.contacts_info4 = "Cualquier participante puede eliminar definitivamente el historial de chat";
out.settings_cat_account = "Cuenta";
out.settings_cat_drive = "CryptDrive";
out.settings_backupCategory = "Copia de seguridad";
out.settings_resetNewTitle = "Limpiar CryptDrive";
out.settings_resetButton = "Eliminar";
out.settings_resetTipsAction = "Reiniciar";
out.settings_userFeedbackTitle = "Feedback";
out.settings_logoutEverywhereButton = "Cerrar sesión";
out.upload_title = "Subir archivo";
// 1.12.0 - Minotaur
out.userlist_pending = "Pendiente...";
out.contacts_typeHere = "Escribe un mensaje aquí...";
out.contacts_removeHistoryTitle = "Borrar el historial de chat";
out.contacts_confirmRemoveHistory = "¿Estás seguro de que quieres borrar el historial de forma permanente? No se podrán recuparar los datos.";
out.contacts_removeHistoryServerError = "Hubo un error al borrar el historial. Inténtalo de nuevo más tarde.";
out.todo_title = "CryptTodo";
out.todo_newTodoNamePlaceholder = "Describe tu tarea...";
out.todo_newTodoNameTitle = "Añadir tarea a la lista";
out.todo_markAsCompleteTitle = "Marcar esta tarea como completa";
out.todo_markAsIncompleteTitle = "Marcar esta tarea como incompleta";
out.todo_removeTaskTitle = "Borrar esta tarea de la lista";
// 1.13.0 - Naiad
out.topbar_whatIsCryptpad = "Qué es CryptPad";
out.header_homeTitle = "Volver a la página de inicio";
out.userListButton = "Lista de usuarios";
out.userAccountButton = "Tu cuenta";
out.canvas_saveToDrive = "Guardar esta imagen como archivo en tu CryptDrive";
out.canvas_currentBrush = "Pincel actual";
out.canvas_chooseColor = "Eligir un color";
out.fm_viewListButton = "Lista";
out.fm_viewGridButton = "Cuadrícula";
out.settings_cat_code = "Código";
out.settings_codeIndentation = "Indentación del editor de código (espacios)";
out.settings_codeUseTabs = "Utilizar tabulaciones en vez de espacios";
out.pad_showToolbar = "Mostrar la barra de herramientas";
out.pad_hideToolbar = "Esconder la barra de herramientas";
out.main_catch_phrase = "El Cloud Zero Knowledge";
out.main_richTextPad = "Pad de Texto Enriquecido";
out.main_codePad = "Pad de Código";
out.main_slidePad = "Presentación Markdown";
out.main_pollPad = "Encuesta";
out.main_whiteboardPad = "Pizarra";
out.main_localPads = "Pad Locales";
out.main_yourCryptDrive = "Tu CryptDrive";
return out;
/*
* You can override the translation text using this file.
* The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js)
in a 'customize' directory (/customize/translations/messages.{LANG}.js).
* If you want to check all the existing translation keys, you can open the internal language file
but you should not change it directly (/common/translations/messages.{LANG}.js)
*/
define(['/common/translations/messages.es.js'], function (Messages) {
// Replace the existing keys in your copied file here:
// Messages.button_newpad = "New Rich Text Document";
return Messages;
});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,162 +1,14 @@
define(function () {
var out = {};
/*
* You can override the translation text using this file.
* The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js)
in a 'customize' directory (/customize/translations/messages.{LANG}.js).
* If you want to check all the existing translation keys, you can open the internal language file
but you should not change it directly (/common/translations/messages.{LANG}.js)
*/
define(['/common/translations/messages.pl.js'], function (Messages) {
// Replace the existing keys in your copied file here:
// Messages.button_newpad = "New Rich Text Document";
// translations must set this key for their language to be available in
// the language dropdowns that are shown throughout Cryptpad's interface
out._languageName = 'Polish';
out.main_title = "Cryptpad: Wspólne edytowanie w czasie rzeczywistym, bez wiedzy specjalistycznej";
out.main_slogan = "Jedność siłą - Współpraca kluczem";
out.type = {};
out.type.pad = 'Pad';
out.type.code = 'Kod';
out.type.poll = 'Balot';
out.type.slide = 'Prezentacja';
out.common_connectionLost = 'Przerwano połączenie z serwerem';
out.disconnected = 'Rozłączony';
out.synchronizing = 'Synchronizacja';
out.reconnecting = 'Wznawianie połączenia...';
out.lag = 'Lag';
out.readonly = 'Tylko do odczytu';
out.anonymous = "Anonimowy";
out.yourself = "Ty";
out.anonymousUsers = "użytkownicy anonimowi";
out.anonymousUser = "użytkownik anonimowy";
out.users = "Użytkownicy";
out.and = "i";
out.viewer = "czytający";
out.viewers = "czytających";
out.editor = "edytujący";
out.editors = "edytujących";
out.greenLight = "Wszystkie systemy działają poprawnie";
out.orangeLight = "Słabe łącze może wpłynąć na działanie aplikacji";
out.redLight = "Zostałeś rozłączony z sesją";
out.importButtonTitle = 'Importuj dokument z pliku lokalnego';
out.exportButtonTitle = 'Zapisz ten dokument do pliku';
out.exportPrompt = 'Jak chciałbyś nazwać swój plik?';
out.changeNamePrompt = 'Zmień swoją nazwę (Pozostaw puste, by być anonimowym): ';
out.clickToEdit = "Naciśnij by edytować";
out.forgetButtonTitle = 'Usuń ten dokument z listy wyświetlanej na stronie głównej';
out.forgetPrompt = 'Wciskając OK usuniesz ten URL z pamięci lokalnej, jesteś tego pewien?';
out.shareButton = 'Udostępnij';
out.shareSuccess = 'Pomyślnie skopiowano URL';
out.presentButtonTitle = "Otwórz tryb prezentacji";
out.backgroundButtonTitle = 'Zmień kolor tła dla tej prezentacji';
out.colorButtonTitle = 'Zmień kolor tekstu dla tej prezentacji';
out.editShare = "Udostępnij URL do edycji";
out.editShareTitle = "Zapisz URL do edycji w schowku";
out.viewShare = "Udostępnij URL tylko do odczytu";
out.viewShareTitle = "Zapisz URL tylko do odczytu w schowku";
out.viewOpen = "Otwórz podgląd w nowej karcie";
out.viewOpenTitle = "Otwórz ten dokument w nowej karcie, tylko do odczytu";
out.notifyJoined = "{0} dołączył do sesji współpracy";
out.notifyRenamed = "{0} jest teraz znany jako {1}";
out.notifyLeft = "{0} opuścił sesję współpracy";
out.tryIt = 'Wypróbuj!';
out.okButton = 'OK (enter)';
out.cancelButton = 'Anuluj (esc)';
// Polls
out.poll_title = "Prosty koordynator spotkań"; // Choice of "Koordynator" can be discussed
out.poll_subtitle = "Proste planowanie spotkań, <em>w czasie rzeczywistym</em>";
out.poll_p_save = "Twoje ustawienia aktualizowane są na bieżąco. Nie martw się zapisywaniem.";
out.poll_p_encryption = "Wszystko co robisz jest szyfrowane, więc tylko osoby z linkiem mają tu dostęp. Nawet serwer nie widzi co kombinujesz.";
out.wizardLog = "Naciśnij przycisk w lewym-górnym rogu by wrócić do planu";
out.wizardTitle = "Uzyj kreatora by stworzyć opcje do głosowania";
out.wizardConfirm = "Jesteś pewny, że chcesz dodać te opcje do głosowania?";
out.poll_closeWizardButton = "Zamknij kreator";
out.poll_closeWizardButtonTitle = "Zamyka kreator";
out.poll_wizardComputeButton = "Ustawienia kalkulacji";
out.poll_wizardClearButton = "Wyczyść tabelę";
out.poll_wizardDescription = "Automatycznie stwórz część opcji poprzez wpisanie ilości dat i godzin";
out.poll_wizardAddDateButton = "+ Daty";
out.poll_wizardAddTimeButton = "+ Godziny";
out.poll_optionPlaceholder = "Opcja";
out.poll_userPlaceholder = "Twoje imię";
out.poll_removeOption = "Jesteś pewien, że chcesz usunąć tę opcję?";
out.poll_removeUser = "Jesteś pewien, że chcesz usunąć tego użytkownika?";
out.poll_titleHint = "Tytuł";
out.poll_descriptionHint = "Opis";
// index.html
out.main_p2 = 'Ten projekt wykorzystuje wizualny edytor <a href="http://ckeditor.com/">CKEditor</a> , <a href="https://codemirror.net/">CodeMirror</a>, oraz silnik czasu rzeczywistego <a href="https://github.com/xwiki-contrib/chainpad">ChainPad</a>.';
out.main_howitworks = 'Jak to działa';
out.main_howitworks_p1 = 'CryptPad wykorzystuje wariant algorytmu <a href="https://en.wikipedia.org/wiki/Operational_transformation">Transformacji operacyjnej</a> który jest wstanie odnaleźć rozdzielony konsensus wprowadzanych danych. Używa do tego <a href="https://bitcoin.org/bitcoin.pdf">Łańcuch blokowy Nakamoto</a>, twór zpopularyzowany przez <a href="https://en.wikipedia.org/wiki/Bitcoin">Bitcoin</a>. W ten sposób algorytm może pominąć potrzebę centralnego serwera do rozwiązywania Konfliktów Operacji Przekształcania poprzez Edycję. Bez potrzeby rozwiązywania konfliktów, serwer może pozostać w niewiedzy o zawartości która jest edytowana w dokumencie.';
out.main_about_p2 = 'Jeżeli masz jakieś pytania lub komentarze, możesz napisać na <a href="https://twitter.com/cryptpad">tweeterze</a>, otworzyć problem na <a href="https://github.com/xwiki-labs/cryptpad/issues/" title="our issue tracker">githubie</a>, przywitać się na ircu (<a href="http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7" title="freenode webchat">irc.freenode.net</a>), lub wysłać nam <a href="mailto:research@xwiki.com">email</a>.';
out.button_newpad = 'STWÓRZ PAD WYSIWYG';
out.button_newcode = 'STWÓRZ PAD DO KODU';
out.button_newpoll = 'STWÓRZ GŁOSOWANIE';
out.button_newslide = 'STWÓRZ PREZENTACJĘ';
// privacy.html
out.policy_title = 'Polityka prywatności CryptPad';
out.policy_whatweknow = 'Co o tobie wiemy';
out.policy_whatweknow_p1 = 'Jako aplikacja udostępniana w internecie, CryptPad ma dostęp do metadanych wystawianych przez protokół HTTP. W skład tych danych wchodzi adres IP oraz różne inne nagłówki HTTP które pozwalają na identyfikację twojej przeglądarki. Możesz podejrzeć jakie informacje udostępnia twoja przeglądarka odwiedzając <a target="_blank" rel="noopener noreferrer" href="https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending" title="what http headers is my browser sending">WhatIsMyBrowser.com</a>.';
out.policy_whatweknow_p2 = 'Używamy <a href="https://piwik.org/" target="_blank" rel="noopener noreferrer" title="open source analytics platform">Piwik</a>, Open Sourcowej platformy analitycznej, aby dowiedzieć się czegoś o naszych użytkownikach. Piwik mówi nam, skąd dowiedziałeś się o Cryptpad. Bezpośrednio przez adres, silnik wyszukiwany, czy z polecenia innej usługi internetowej jak Reddit czy Twitter. Uczymy się również gdy nas odwiedzasz, jakie linki odwiedzasz z naszej strony informacyjnej i jak długo pozostajesz na konkretnych stronach.';
out.policy_howweuse = 'Jak wykorzystujemy zebraną wiedzę';
out.policy_howweuse_p1 = 'Dzieki tym informacjom możemy podejmować lepsze decyzje przy promocji CryptPad, poprzez ocenę które z podjętych przez nas prób okazały się udane. Informacja o twojej lokalizacji daje nam znać, czy powinniśmy zapewnić lepsze wsparcie dla języków poza Angielskim.';
out.policy_howweuse_p2 = "Informacje o twojej przeglądarce (czy jest to aplikacja desktopowa, czy działająca na systemie mobilnym) pozwalają nam na decydowanie przy priorytezowaniu ulepszeń funkcji. Nasz zespół deweloperski jest mały, a my staramy się dokonywać wyborów które poprawią doświadczenia jak największej liczby użytkowników.";
out.policy_whatwetell = 'Jakie dane przekazujemy innym';
out.policy_whatwetell_p1 = 'Nie dostarczamy osobom trzecim żadnych danych które udało się nam zebrać, lub tych które nam przekazałeś sam, dopóki nie jesteśmy do tego zobligowani prawnie.';
out.policy_links = 'Adresy innych stron';
out.policy_links_p1 = 'Ta witryna zawiera łącza do innych stron, włączając w to te stworzone przez inne organizacje. Nie jesteśmy odpowiedzialni za praktyki dotyczące prywatności oraz zawartość usługodawców poza tą witryną. Jako główną zasadę przyjmujemy, że łącza do stron zewnętrznych uruchamiane są w nowej karcie lub oknie, aby upewnić cię iż opuszczasz Cryptpad.';
out.policy_ads = 'Promocja i reklama';
out.policy_ads_p1 = 'Nie wyświetlamy żadnej zawartości promocyjnej online, choć możemy udostępniać łącza do podmiotów finansujących nasze badania.';
out.policy_choices = 'Co możesz zrobić';
out.policy_choices_open = 'Nasz kod jest open source, więc zawsze masz możliwość hostowania swojej własnej wersji Cryptpad.';
out.policy_choices_vpn = 'Jeżeli chcesz korzystać z wersji udostępnianej przez nas, lecz nie chcesz pokazywać swojego adresu IP, możesz chronić swój adres wykorzystując <a href="https://www.torproject.org/projects/torbrowser.html.en" title="downloads from the Tor project" target="_blank" rel="noopener noreferrer">przeglądarki Tor</a>, lub <a href="https://riseup.net/en/vpn" title="VPNs provided by Riseup" target="_blank" rel="noopener noreferrer">VPN</a>.';
out.policy_choices_ads = 'Masz również możliwość blokady naszej platformy analitycznej wykorzystując narzędzia adblock, takie jak <a href="https://www.eff.org/privacybadger" title="download privacy badger" target="_blank" rel="noopener noreferrer">Privacy Badger</a>.';
// terms.html
out.tos_title = "Warunki korzystania z usług Cryptpad";
out.tos_legal = "Prosimy abyś nie był złośliwy, obelżywy i nie wykorzystywał tego oprogramowania do celow niezgodnych z prawem.";
out.tos_availability = "Mamy nadzieję iż uznasz tę usługę za przydatną, lecz dostępność i wydajność nie mogą być przez nas gwarantowane. Prosimy, abyś eksportował swoje dane regularnie.";
out.tos_e2ee = "Dokumenty Cryptpad mogą być odczytywane i modyfikowane przez każdego kto może zgadnąć lub w inny sposób uzyskać identyfikator dokumentu. Polecamy korzystania z oprogramowania szyfrującego end-to-end (e2ee) do udostępniania linków URL. Nie będziesz rościł sobie żadnych wierzytelności w wypadku gdy taki URL dostanie się w niepowołane ręce.";
out.tos_logs = "Metadane dostarczane przez twoją przeglądarkę do serwera mogą być zapisywane i przechowywane w celu utrzymywania serwisu.";
out.tos_3rdparties = "Nie dostarczamy indywidualizowanych danych do osób trzecich, poza sytuacjami dyktowanymi prawnie.";
// BottomBar.html
out.bottom_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Stworzone z <img class="bottom-bar-heart" src="/customize/heart.png" /> we <img class="bottom-bar-fr" src="/customize/fr.png" /></a>';
out.bottom_support = '<a href="http://labs.xwiki.com/" title="XWiki Labs" target="_blank" rel="noopener noreferrer">Projekt <img src="/customize/logo-xwiki2.png" alt="XWiki SAS" class="bottom-bar-xwiki"/> Labs </a> we wspolpracy z <a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
// Header.html
out.header_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Pełne <img class="bottom-bar-heart" src="/customize/heart.png" /> z <img class="bottom-bar-fr" src="/customize/fr.png" title="France" alt="France"/> od <img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
// TODO Hardcode cause YOLO
//out.header_xwiki = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer"><img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
out.header_support = '<a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
out.header_logoTitle = 'Przejdź na stronę główną';
return out;
return Messages;
});

View File

@ -1,546 +1,14 @@
// Tradução para protuguês brasileiro efetuada por Gustavo Henrique Machado da Silva (www.linkedin.com/in/gustavohmsilva)
// Embora o software original possa não possuir as mesmas licenças, a tradução produzida por mim é protegida sob termos
// Creative Commons, Attribution-ShareAlike 4.0 International
// Contate-me via email no endereço gustavohmsilva@member.fsf.org
// Translation to brazilian portuguese done by Gustavo Henrique Machado da Silva (www.linkedin.com/in/gustavohmsilva)
// Even though this software may not share the same licenses, the translation produced by me is protected under
// Creative commons, Attribution-ShareAlike 4.0 International
// You can contact me over email on gustavohmsilva@member.fsf.org
define(function () {
var out = {};
out._languageName = 'Brazilian Portuguese';
out.main_title = "Cryptpad: Zero Knowledge, Edição Colaborativa em Tempo Real";
out.main_slogan = "União é Força - Colaboração é a Chave";
out.type = {};
out.type.pad = 'Notas';
out.type.code = 'Código';
out.type.poll = 'votação';
out.type.slide = 'Apresentação';
out.type.drive = 'Drive';
out.type.whiteboard = 'Whiteboard';
out.type.file = 'File';
out.type.media = 'Media';
out.button_newpad = 'Novo bloco RTF';
out.button_newcode = 'Novo bloco de código';
out.button_newpoll = 'Novo questionário';
out.button_newslide = 'Nova apresentação';
out.button_newwhiteboard = 'Novo quadro branco';
// NOTE: We want to update the 'common_connectionLost' key.
// Please do not add a new 'updated_common_connectionLostAndInfo' but change directly the value of 'common_connectionLost'
out.updated_0_common_connectionLost = "<b>Conexão com o Servidor Perdida</b><br>Você agora está em modo somente leitura até a conexão ser restaurada.";
out.common_connectionLost = out.updated_0_common_connectionLost;
out.websocketError = 'Incapaz de se conectar com o servidor websocket...';
out.typeError = "Este bloco não é compatível com a aplicação selecionada";
out.onLogout = 'você foi desconectado, {0}clique aqui{1} para se conectar, <br>ou pressione <em>ESC</em> para acessar seu bloco em modo somente leitura.';
out.wrongApp = "Incapaz de mostrar o conteúdo em tempo real no seu navegador. Por favor tente recarregar a página.";
out.loading = "Carregando...";
out.error = "Erro";
out.saved = "Salvo";
out.synced = "Tudo foi salvo";
out.deleted = "Bloco deletado do seu CryptDrive";
out.disconnected = 'Desconectado';
out.synchronizing = 'Sincronizando';
out.reconnecting = 'Reconectando...';
out.lag = 'Lag';
out.readonly = 'Somente leitura';
out.anonymous = "Anonimo";
out.yourself = "Você";
out.anonymousUsers = "Usuários anônimos";
out.anonymousUser = "Usuário anônimo";
out.users = "Usuários";
out.and = "e";
out.viewer = "vizualizações";
out.viewers = "leitores";
out.editor = "editor";
out.editors = "editores";
out.language = "Lingua";
out.comingSoon = "Em breve...";
out.newVersion = '<b>O CryptPad foi atualizado!</b><br>' +
'Cheque as novidades na última versão:<br>'+
'<a href="https://github.com/xwiki-labs/cryptpad/releases/tag/{0}" target="_blank">Notas da atualização do CryptPad {0}</a>';
out.upgrade = "Upgrade";
out.upgradeTitle = "Faça um upgrade na sua conta para aumentar o limite de armazenamento";
out.MB = "MB";
out.GB = "GB";
out.KB = "KB";
out.formattedMB = "{0} MB";
out.formattedGB = "{0} GB";
out.formattedKB = "{0} KB";
out.greenLight = "Tudo está funcionando bem";
out.orangeLight = "Sua conexão lenta pode impactar sua experiência";
out.redLight = "Você está desconectado da sua sessão";
out.pinLimitReached = "Você alcançou o limite de armazenamento";
out.updated_0_pinLimitReachedAlert = "Você alcançou o limite de armazenamento. Novos blocos não serão mais salvos no seu CryptDrive.<br>" +
'Você pode deletar blocos do seu CryptDrive ou <a href="https://accounts.cryptpad.fr/#!on={0}" target="_blank">se inscrever como premium</a> para aumentar o limite de espaço.';
out.pinLimitReachedAlert = out.updated_0_pinLimitReachedAlert;
out.pinAboveLimitAlert = 'A partir desta atualização, nós estamos impondo um limite de 50MB no armazenamento gratuito. Você está atualmente usando {0}. Você irá precisar deletar alguns blocos ou se inscrever no <a href="https://accounts.cryptpad.fr/#!on={1}" target="_blank">accounts.cryptpad.fr</a>. Sua contribuição irá nos ajudar a melhorar o CryptPad e expandir a metodologia Zero Knowledge. Por favor contacte o <a href="https://accounts.cryptpad.fr/#/support" target="_blank">suporte</a> se você possui outras dúvidas.';
out.pinLimitNotPinned = "Você alcançou o limite de armazenamento.<br>"+
"Este bloco não está armazenado no seu CryptDrive.";
out.pinLimitDrive = "Você alcançou o limite de armazenamento.<br>" +
"Você não pode criar novos blocos.";
out.importButtonTitle = 'Importar um documento de um arquivo local';
out.exportButtonTitle = 'Exportar esta sesão para um arquivo local';
out.exportPrompt = 'Como deseja nomear seu arquivo?';
out.changeNamePrompt = 'Mude seu nome (deixe em branco para se manter anônimo): ';
out.user_rename = "Mudar nome de exibição";
out.user_displayName = "Nome visível";
out.user_accountName = "Nome da Conta";
out.clickToEdit = "Clique para Editar";
out.forgetButtonTitle = 'Remova este documento da listagem da sua página';
out.forgetPrompt = 'Clicando OK você irá remover o endereço deste bloco de notas do armazenamento local, você tem certeza?';
out.movedToTrash = 'That pad has been moved to the trash.<br><a href="/drive/">Access my Drive</a>';
out.shareButton = 'Compartilhar';
out.shareSuccess = 'Endereço copiado para o clipboard';
out.newButton = 'Novo';
out.newButtonTitle = 'Criar um novo bloco';
out.saveTemplateButton = "Salvar como modelo";
out.saveTemplatePrompt = "Escolha o nome do modelo";
out.templateSaved = "Modelo salvo!";
out.selectTemplate = "Selecione um modelo ou pressione ESC";
out.previewButtonTitle = "Mostrar ou esconder o modo de visualização markdown";
out.presentButtonTitle = "Entrar no modo apresentação";
out.backgroundButtonTitle = 'Mudar cor do fundo da apresentação';
out.colorButtonTitle = 'Mudar a cor do texto no modo apresentação';
out.printButton = "Imprimir (Enter)";
out.printButtonTitle = "Imprimir seus slides ou exportá-los como PDF";
out.printOptions = "Opções de leiaute";
out.printSlideNumber = "Mostrar o número do slide";
out.printDate = "Mostrar a data";
out.printTitle = "Mostrar título do bloco";
out.printCSS = "Custom style rules (CSS):";
out.printTransition = "Ativar animações de transição";
out.slideOptionsTitle = "Personalizar seus slides";
out.slideOptionsButton = "Salvar (Enter)";
out.editShare = "Compartilhar endereço editável";
out.editShareTitle = "Copiar endereço editável";
out.editOpen = "Abrir endereço editável em nova aba";
out.editOpenTitle = "Abrir este bloco em modo editável em nova aba";
out.viewShare = "Compartilhar endereço de visualização";
out.viewShareTitle = "Copiar o endereço somente leitura";
out.notifyJoined = "{0} entraram na sessão colaborativa";
out.notifyRenamed = "{0} agora é conhecido como {1}";
out.notifyLeft = "{0} deixou essa sessão colaborativa";
out.okButton = 'OK (Enter)';
out.cancel = "Cancelar";
out.cancelButton = 'Cancelar (ESC)';
out.historyButton = "Exibir histórico do documento";
out.history_next = "Ir para próxima versão";
out.history_prev = "Ir para versão anterior";
out.history_goTo = "Ir para versão selecionada";
out.history_close = "Voltar";
out.history_closeTitle = "Fechar o histórico";
out.history_restore = "Restaurar";
out.history_restoreTitle = "Restaurar a versão selecionada do documento";
out.history_restorePrompt = "Você tem certeza que deseja substituir a versão atual do documento pela que está sendo exibida agora?";
out.history_restoreDone = "Documento restaurado";
out.history_version = "Versão:";
out.tryIt = 'Experimente!';
// Polls
out.poll_title = "Seletor de dados zero knowledge";
out.poll_subtitle = "Zero Knowledge, agendamento <em>em tempo real</em>";
out.poll_p_save = "Suas configurações são atualizadas instantaneamente, assim você nunca terá de salvá-las";
out.poll_p_encryption = "Tudo que der entrada é encriptado para que apenas as pessoas com o link possam acessá-las. Nem mesmo o servidor pode ver suas mudanças.";
out.wizardLog = "Clique no botão no topo esquerdo para voltar para sua enquete";
out.wizardTitle = "Use o assistente para criar sua enquete";
out.wizardConfirm = "Você está realmente pronto para adicionar estas opções em sua enquete?";
out.poll_publish_button = "Publicar";
out.poll_admin_button = "Admin";
out.poll_create_user = "Adicionar novo usuário";
out.poll_create_option = "Adicionar nova opção";
out.poll_commit = "Submeter";
out.poll_closeWizardButton = "Fechar assistente";
out.poll_closeWizardButtonTitle = "Fechar assistente";
out.poll_wizardComputeButton = "Computar opções";
out.poll_wizardClearButton = "Limpar tabela";
out.poll_wizardDescription = "Automaticamente criar um número de opções entrando qualquer número de seguimentos de datas e horários";
out.poll_wizardAddDateButton = "+ Datas";
out.poll_wizardAddTimeButton = "+ Horários";
out.poll_optionPlaceholder = "Alternativa";
out.poll_userPlaceholder = "Seu nome";
out.poll_removeOption = "Você tem certeza que deseja remover esta opção?";
out.poll_removeUser = "Você tem certeza que quer remover este usuário?";
out.poll_titleHint = "Título";
out.poll_descriptionHint = "Descrição";
// Canvas
out.canvas_clear = "Limpar";
out.canvas_delete = "Deletar seleção";
out.canvas_disable = "Desabilitar desenho";
out.canvas_enable = "Habilitar desenho";
out.canvas_width = "Largura";
out.canvas_opacity = "Opacidade";
// File manager
out.fm_rootName = "Documentos";
out.fm_trashName = "Lixeira";
out.fm_unsortedName = "Arquivos não organizados";
out.fm_filesDataName = "Todos os Arquivos";
out.fm_templateName = "Temas";
out.fm_searchName = "Busca";
out.fm_searchPlaceholder = "Buscar...";
out.fm_newButton = "Novo";
out.fm_newButtonTitle = "Criar um novo bloco ou diretório";
out.fm_newFolder = "Novo diretório";
out.fm_newFile = "Novo bloco";
out.fm_folder = "Diretório";
out.fm_folderName = "Nome do diretório";
out.fm_numberOfFolders = "# de diretórios";
out.fm_numberOfFiles = "# de arquivos";
out.fm_fileName = "Nome do arquivo";
out.fm_title = "Título";
out.fm_type = "Tipo";
out.fm_lastAccess = "Último acesso";
out.fm_creation = "Criação";
out.fm_forbidden = "Ação não permitida";
out.fm_originalPath = "Caminho original";
out.fm_openParent = "Exibir no diretório";
out.fm_noname = "Documento sem título";
out.fm_emptyTrashDialog = "Você tem certeza que deseja limpar a lixeira??";
out.fm_removeSeveralPermanentlyDialog = "Você tem certeza que deseja deletar estes {0} elementos da lixeira permanentemente?";
out.fm_removePermanentlyDialog = "Você tem certeza que deseja deletar este elemento da lixeira permanentemente?";
out.fm_removeSeveralDialog = "Você tem certeza que deseja mover estes {0} elementos para a lixeira?";
out.fm_removeDialog = "Você tem certeza que deseja mover {0} para a lixeira?";
out.fm_restoreDialog = "Você tem certeza que deseja restaurar {0} de volta para seu diretório original?";
out.fm_unknownFolderError = "O diretório selecionado ou visitado por último não existe mais. Abrindo diretório superior...";
out.fm_contextMenuError = "Incapaz de abrir o menu de contextualização para este elementos. Se o problema persistir, tente recarregar a página.";
out.fm_selectError = "Incapaz de selecionar o elemento marcado. Se o problema persistir, tente recarregar a página.";
out.fm_categoryError = "Incapaz de abrir a categoria selecionada, Exibindo diretório raiz";
out.fm_info_root = "Crie quantos diretórios aninhados aqui desejar para organizar seus arquivos..";
out.fm_info_unsorted = "Contém todos os arquivos que você visitou e não estão ainda organizados na pasta Documentos ou foram movidos para a pasta lixeira"; // "My Documents" should match with the "out.fm_rootName" key, and "Trash" with "out.fm_trashName" out.fm_info_template = 'Contains all the pads stored as templates and that you can re-use when you create a new pad.';
out.updated_0_fm_info_trash = 'Empty your trash to free space in your CryptDrive.';
out.fm_info_trash = out.updated_0_fm_info_trash;
out.fm_info_allFiles = 'Contém todos os arquivos de "Documentos", "Não organizados" e "Lixeira". Não é possível mover ou remover arquivos daqui.'; // Same here
out.fm_info_anonymous = 'Você não está logado, então estes blocos podem ser deletados! (<a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">Descubra o porque</a>). ' +
'<a href="/register/">Cadastre-se</a> or <a href="/login/">Entre</a> Para deixá-los salvos.';
out.fm_alert_backupUrl = "Link de backup desta conta.<br>" +
"É <strong>fortemente recomendado</strong> que você deixe para você e somente você.<br>" +
"Você pode usá-lo para resgatar os seus dados caso a memória do seu navegador se perca.<br>" +
"Qualquer um com este link pode editar ou apagar todos os arquivos no gerenciador da conta.<br>";
out.fm_alert_anonymous = "Ola! Você está utilizando o CryptPad anonimamente, isto é ok, mas seus blocos podem ser apagados " +
"se ficarem muito tempo inativo. Nós desativamos as funções avançadas nas contas anônimas para que isto fique claro para você " +
'Este não é um bom lugar apra salvar senhas! Entenda: <a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">Clicando aqui!</a> ' +
'Porque estamos fazendo isso e porque você deveria criar uma onta? <a href="/register/">Sign up</a> and <a href="/login/">Clique e entenda!</a>.';
out.fm_backup_title = 'Link de restauração';
out.fm_nameFile = 'Como deseja nomear este arquivo?';
out.fm_error_cantPin = "Erro interno do servidor. Por favor recarregue a página e tente novamente.";
// File - Context menu
out.fc_newfolder = "Nova pasta";
out.fc_rename = "Renomear";
out.fc_open = "Abrir";
out.fc_open_ro = "Abrir (somente leitura)";
out.fc_delete = "Deletar";
out.fc_restore = "Restaurar";
out.fc_remove = "Deletar permanentemente";
out.fc_empty = "Esvaziar lixeira";
out.fc_prop = "Propriedades";
out.fc_sizeInKilobytes = "tamanho em Kilobytes";
// fileObject.js (logs)
out.fo_moveUnsortedError = "Você não pode mover uma pasta na lista de notas não organizadas";
out.fo_existingNameError = "Nome já em uso neste diretório. Por favor escolha outro.";
out.fo_moveFolderToChildError = "Você não pode mover uma sub-diretório para dentro de um de seus sub-diretórios";
out.fo_unableToRestore = "Fomos incapazes de restaurar este arquivo para sua posição original. Você pode tentar move-lo para o local de destino porém.";
out.fo_unavailableName = "Um arquivo ou diretório com o mesmo nome já existe no novo locao. Renomeie-o e tente novamente.";
// login
out.login_login = "Entrar";
out.login_makeAPad = 'Criar bloco anonimamente';
out.login_nologin = "Navegar nos blocos locais";
out.login_register = "Cadastro";
out.logoutButton = "Sair";
out.settingsButton = "Configurações";
out.login_username = "Usuário";
out.login_password = "Senha";
out.login_confirm = "Confirme sua senha";
out.login_remember = "Memorize-me";
out.login_hashing = "Encriptando sua senha, isto pode tomar algum tempo.";
out.login_hello = 'Ola {0},'; // {0} is the username
out.login_helloNoName = 'Ola,';
out.login_accessDrive = 'Acesse seu diretório';
out.login_orNoLogin = 'ou';
out.login_noSuchUser = 'Usuário ou senha inválido. Tente nocamente ou cadastre-se';
out.login_invalUser = 'É necessário um usuário';
out.login_invalPass = 'É necessário uma senha';
out.login_unhandledError = 'Um erro não esperado ocorreu :(';
out.register_importRecent = "Importar histórico de blocos (Recomendado)";
out.register_acceptTerms = "Eu aceito <a href='/terms.html'>os termos de serviço</a>";
out.register_passwordsDontMatch = "Senhas não coincidem!";
out.register_mustAcceptTerms = "Você precisa aceitar os termos de serviço.";
out.register_mustRememberPass = "Nós não podemos restaurar sua senha caso você a esqueça. É muito importante que você lembre-se dela! Clique nesta caixa de seleção para confirmar que você compreendeu isto.";
out.register_header = "Bem vindo ao CryptPad";
out.register_explanation = [
"<p>Lets go over a couple things first</p>",
"<ul>",
"<li>Your password is your secret key which encrypts all of your pads. If you lose it there is no way we can recover your data.</li>",
"<li>You can import pads which were recently viewed in your browser so you have them in your account.</li>",
"<li>If you are using a shared computer, you need to log out when you are done, closing the tab is not enough.</li>",
"</ul>"
].join('');
out.register_writtenPassword = "I have written down my username and password, proceed";
out.register_cancel = "Go back";
out.register_warning = "Zero Knowledge means that we can't recover your data if you lose your password.";
out.register_alreadyRegistered = "This user already exists, do you want to log in?";
// Settings
out.settings_title = "Settings";
out.settings_save = "Save";
out.settings_backupTitle = "Backup or restore all your data";
out.settings_backup = "Backup";
out.settings_restore = "Restore";
out.settings_resetTitle = "Clean your drive";
out.settings_reset = "Remove all the files and folders from your CryptDrive";
out.settings_resetPrompt = "This action will remove all the pads from your drive.<br>"+
"Are you sure you want to continue?<br>" +
"Type “<em>I love CryptPad</em>” to confirm.";
out.settings_resetDone = "Your drive is now empty!";
out.settings_resetError = "Incorrect verification text. Your CryptDrive has not been changed.";
out.settings_resetTips = "Tips in CryptDrive";
out.settings_resetTipsButton = "Reset the available tips in CryptDrive";
out.settings_resetTipsDone = "All the tips are now visible again.";
out.settings_importTitle = "Import this browser's recent pads in my CryptDrive";
out.settings_import = "Import";
out.settings_importConfirm = "Are you sure you want to import recent pads from this browser to your user account's CryptDrive?";
out.settings_importDone = "Import completed";
out.settings_userFeedbackHint1 = "CryptPad provides some very basic feedback to the server, to let us know how to improve your experience.";
out.settings_userFeedbackHint2 = "Your pad's content will never be shared with the server.";
out.settings_userFeedback = "Enable user feedback";
out.settings_anonymous = "You are not logged in. Settings here are specific to this browser.";
out.settings_publicSigningKey = "Public Signing Key";
out.settings_usage = "Usage";
out.settings_usageTitle = "See the total size of your pinned pads in MB";
out.settings_pinningNotAvailable = "Pinned pads are only available to registered users.";
out.settings_pinningError = "Something went wrong";
out.settings_usageAmount = "Your pinned pads occupy {0}MB";
out.settings_logoutEverywhereTitle = "Log out everywhere";
out.settings_logoutEverywhere = "Log out of all other web sessions";
out.settings_logoutEverywhereConfirm = "Are you sure? You will need to log in with all your devices.";
out.upload_serverError = "Server Error: unable to upload your file at this time.";
out.upload_uploadPending = "You already have an upload in progress. Cancel it and upload your new file?";
out.upload_success = "Your file ({0}) has been successfully uploaded and added to your drive.";
out.upload_notEnoughSpace = "There is not enough space for this file in your CryptDrive.";
out.upload_tooLarge = "This file exceeds the maximum upload size.";
out.upload_choose = "Choose a file";
out.upload_pending = "Pending";
out.upload_cancelled = "Cancelled";
out.upload_name = "File name";
out.upload_size = "Size";
out.upload_progress = "Progress";
out.download_button = "Decrypt & Download";
// general warnings
out.warn_notPinned = "This pad is not in anyone's CryptDrive. It will expire after 3 months. <a href='/about.html#pinning'>Learn more...</a>";
// index.html
//about.html
out.main_p2 = 'This project uses the <a href="http://ckeditor.com/">CKEditor</a> Visual Editor, <a href="https://codemirror.net/">CodeMirror</a>, and the <a href="https://github.com/xwiki-contrib/chainpad">ChainPad</a> realtime engine.';
out.main_howitworks_p1 = 'CryptPad uses a variant of the <a href="https://en.wikipedia.org/wiki/Operational_transformation">Operational transformation</a> algorithm which is able to find distributed consensus using a <a href="https://bitcoin.org/bitcoin.pdf">Nakamoto Blockchain</a>, a construct popularized by <a href="https://en.wikipedia.org/wiki/Bitcoin">Bitcoin</a>. This way the algorithm can avoid the need for a central server to resolve Operational Transform Edit Conflicts and without the need for resolving conflicts, the server can be kept unaware of the content which is being edited on the pad.';
// contact.html
out.main_about_p2 = 'If you have any questions or comments, you can <a href="https://twitter.com/cryptpad">tweet us</a>, open an issue <a href="https://github.com/xwiki-labs/cryptpad/issues/" title="our issue tracker">on github</a>, come say hi on irc (<a href="http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7" title="freenode webchat">irc.freenode.net</a>), or <a href="mailto:research@xwiki.com">send us an email</a>.';
out.main_info = "<h1>Collaborate in Confidence</h1><br> Grow your ideas together with shared documents while <strong>Zero Knowledge</strong> technology secures your privacy; even from us.";
out.main_howitworks = 'How It Works';
out.main_zeroKnowledge = 'Zero Knowledge';
out.main_zeroKnowledge_p = "You don't have to trust that we <em>won't</em> look at your pads, with CryptPad's revolutionary Zero Knowledge Technology we <em>can't</em>. Learn more about how we protect your <a href=\"/privacy.html\" title='Privacy'>Privacy and Security</a>.";
out.main_writeItDown = 'Write it down';
out.main_writeItDown_p = "The greatest projects come from the smallest ideas. Take down the moments of inspiration and unexpected ideas because you never know which one might be a breakthrough.";
out.main_share = 'Share the link, share the pad';
out.main_share_p = "Grow your ideas together: conduct efficient meetings, collaborate on TODO lists and make quick presentations with all your friends and all your devices.";
out.main_organize = 'Get organized';
out.main_organize_p = "With CryptPad Drive, you can keep your sights on what's important. Folders allow you to keep track of your projects and have a global vision of where things are going.";
out.tryIt = 'Try it out!';
out.main_richText = 'Rich Text editor';
out.main_richText_p = 'Edit rich text pads collaboratively with our realtime Zero Knowledge <a href="http://ckeditor.com" target="_blank">CkEditor</a> application.';
out.main_code = 'Code editor';
out.main_code_p = 'Edit code from your software collaboratively with our realtime Zero Knowledge <a href="https://www.codemirror.net" target="_blank">CodeMirror</a> application.';
out.main_slide = 'Slide editor';
out.main_slide_p = 'Create your presentations using the Markdown syntax, and display them in your browser.';
out.main_poll = 'Polls';
out.main_poll_p = 'Plan your meeting or your event, or vote for the best solution regarding your problem.';
out.main_drive = 'CryptDrive';
out.footer_applications = "Applications";
out.footer_contact = "Contact";
out.footer_aboutUs = "About us";
out.about = "About";
out.privacy = "Privacy";
out.contact = "Contact";
out.terms = "ToS";
out.blog = "Blog";
// privacy.html
out.policy_title = 'Política de privacidade do Cryptpad';
out.policy_whatweknow = 'O que nós sabemos sobre você';
out.policy_whatweknow_p1 = 'Por ser uma aplicação hospedada na web, O Cryptpad tem acesso aos metadados expostos pelo protocolo HTTP. Isso inclui seu endereço IP, e vários cabeçalhos do HTTP que podem ser usados para identificar seu browser particular. Você pode ver que informações seu navegador está compartilhando ao visitar <a target="_blank" rel="noopener noreferrer" href="https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending" title="Que cabeçalhos meu navegador está disponibilizando">WhatIsMyBrowser.com</a>.';
out.policy_whatweknow_p2 = 'Nós usamos a plataforma de análise <a href="https://piwik.org/" target="_blank" rel="noopener noreferrer" title="plataforma analítica open source">Piwik</a>, uma plataforma analítica open source, para aprender mais sobre nossos usos. Piwik nos informa como você encontrou o Cryptpad, via digitação direta, através de mecanismos de busca, ou via link de outro serviço web como o Reddit ou o Twitter. Nós também aprendemos com suas visitas, que links você clica enquanto está em nossas páginas de informações, e quanto tempo você fica nestas páginas.';
out.policy_howweuse = 'Como utilizamos o que nós aprendemos';
out.policy_howweuse_p1 = 'Nos utilizamos estas informações para tomar melhores decisões sobre como promover o Cryptpad, ao avaliar quais dos nosso esforços passados foram mais bem sucedidos. Informações sobre sua localização nos ajudam a decidir se nós devemos considerar prover melhor suporte para idiomas além do inglês.';
out.policy_howweuse_p2 = "As informações sobre o seu navegador de internet (não importando se é um desktop ou um equipamento móvel) nos ajudam a tomar melhores decisões ao priorizar melhorias futuras. Nossa equipe de desenvolvimento é pequena, e nós tentamos fazer as melhores escolhas em pró de auxiliar a experiência de utilização do máximo de nossos usuários possíveis.";
out.policy_whatwetell = 'O que contamos a terceiros sobre você';
out.policy_whatwetell_p1 = 'Nós não informamos terceiros a informação que armazenamos ou que provemos a você, salvo caso sejamos legalmente requisitados a faze-lo.';
out.policy_links = 'Links para outros sites';
out.policy_links_p1 = 'Este site contém ligações para outros sites, incluindo aqueles produzidos por terceiros. Nós não nos responsabilizamos pelas práticas de privacidade ou o conteúdo destes sites. Como regra geral, links para páginas fora de nosso domínio são lançadas em novas janelas ou abas, para deixar claro a todos os visitantes que eles estão deixando o site Cryptpad.fr.';
out.policy_ads = 'Publicidade';
out.policy_ads_p1 = 'Nós não disponibilizamos publicidade online, porém podemos prover links de acesso para obtenção de financiamento para auxiliar em nossa pesquisa e desenvolvimento.';
out.policy_choices = 'As escolhas que você tem';
out.policy_choices_open = 'Nosso código fonte é open source, portanto você sempre tem a opção de hospedar sua própria instância do Cryptpad.';
out.policy_choices_vpn = 'Se você deseja usar nosso site principal, porém não deseja expor seu endereço IP, Você pode se proteger utilizando o <a href="https://www.torproject.org/projects/torbrowser.html.en" title="Baixe o tor" target="_blank" rel="noopener noreferrer">Navegador seguro Tor</a>, ou uma <a href="https://riseup.net/en/vpn" title="VPNs providas pelo Riseup" target="_blank" rel="noopener noreferrer">VPN</a>.';
out.policy_choices_ads = 'Se você deseja apenas bloquear nossa plataforma analítica, você pode utilizar ferramentas de bloqueio de propagandas como o <a href="https://www.eff.org/privacybadger" title="baixe o privacy badger" target="_blank" rel="noopener noreferrer">Privacy Badger</a>.';
// terms.html
out.tos_title = "Termos de serviço doCryptpad";
out.tos_legal = "Pedimos encarecidamente que, como usuário desta plataforma, você evite a prática de quaisquer atos ilegais e que evite a utilização maliciosa e/ou abusiva desta plataforma.";
out.tos_availability = "Nós esperamos que você ache este serviço útil, porém nós não podemos garantir a disponibilidade constante ou a alta performance do mesmo. Por favor, mantenha um backup dos seus dados como forma de segurança adicional.";
out.tos_e2ee = "Os documentos do CryptPad podem ser modificados por qualquer um que conseguir adivinhar ou obter de qualquer forma o seu identificador único. Nós recomendamos que você utilize criptografia ponto a ponto de mensagens (e2ee) sempre que possível para compartilhar suas URL's. Nós não assumimos qualquer responsabilidade sobre chaves e/ou URLs e seus respectivos conteúdos vazadas para o público.";
out.tos_logs = "Os Metadados providos pelo seu navegador para nosso servidor podem ser armazenados com o propósito de manter o serviço em funcionamento";
out.tos_3rdparties = "Nós não disponibilizamos dados individuais para terceiros, salvo quando requisitado legalmente.";
// BottomBar.html
out.bottom_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Feito com <img class="bottom-bar-heart" src="/customize/heart.png" /> na <img class="bottom-bar-fr" src="/customize/fr.png" /></a>';
out.bottom_support = '<a href="http://labs.xwiki.com/" title="XWiki Labs" target="_blank" rel="noopener noreferrer">Um projeto do laboratório <img src="/customize/logo-xwiki2.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a> com o suporte da <a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
// Header.html
out.header_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Com <img class="bottom-bar-heart" src="/customize/heart.png" /> da <img class="bottom-bar-fr" src="/customize/fr.png" title="France" alt="France"/> por <img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
out.header_support = '<a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
out.header_logoTitle = 'Go to the main page';
// Initial states
out.initialState = [
'<p>',
'This is&nbsp;<strong>CryptPad</strong>, the Zero Knowledge realtime collaborative editor. Everything is saved as you type.',
'<br>',
'Share the link to this pad to edit with friends or use the <span class="fa fa-share-alt"></span> button to share a <em>read-only link</em>&nbsp;which allows viewing but not editing.',
'</p>',
].join('');
out.codeInitialState = [
'# CryptPad\'s Zero Knowledge collaborative code editor\n',
'\n',
'* What you type here is encrypted so only people who have the link can access it.\n',
'* You can choose the programming language to highlight and the UI color scheme in the upper right.'
].join('');
out.slideInitialState = [
'# CryptSlide\n',
'1. Write your slides content using markdown syntax\n',
' - Learn more about markdown syntax [here](http://www.markdowntutorial.com/)\n',
'2. Separate your slides with ---\n',
'3. Click on the "Play" button to see the result',
' - Your slides are updated in realtime'
].join('');
// Readme
out.driveReadmeTitle = "What is CryptPad?";
out.readme_welcome = "Welcome to CryptPad !";
out.readme_p1 = "Welcome to CryptPad, this is where you can take note of things alone and with friends.";
out.readme_p2 = "This pad will give you a quick walk through of how you can use CryptPad to take notes, keep them organized and work together on them.";
out.readme_cat1 = "Get to know your CryptDrive";
out.readme_cat1_l1 = "Make a pad: In your CryptDrive, click {0} then {1} and you can make a pad."; // 0: New, 1: Rich Text
out.readme_cat1_l2 = "Open Pads from your CryptDrive: double-click on a pad icon to open it.";
out.readme_cat1_l3 = "Organize your pads: When you are logged in, every pad you access will be shown as in the {0} section of your drive."; // 0: Unsorted files
out.readme_cat1_l3_l1 = "You can click and drag files into folders in the {0} section of your drive and make new folders."; // 0: Documents
out.readme_cat1_l3_l2 = "Remember to try right clicking on icons because there are often additional menus.";
out.readme_cat1_l4 = "Put old pads in the trash: You can click and drag your pads into the {0} the same way you drag them into folders."; // 0: Trash
out.readme_cat2 = "Make pads like a pro";
out.edit = "edit";
out.view = "view";
out.readme_cat2_l1 = "The {0} button in your pad allows you to give access to collaborators to either {1} or to {2} the pad."; // 0: Share, 1: edit, 2: view
out.readme_cat2_l2 = "Change the title of the pad by clicking on the pencil";
out.readme_cat3 = "Discover CryptPad apps";
out.readme_cat3_l1 = "With CryptPad code editor, you can collaborate on code like Javascript and markdown like HTML and Markdown";
out.readme_cat3_l2 = "With CryptPad slide editor, you can make quick presentations using Markdown";
out.readme_cat3_l3 = "With CryptPoll you can take quick votes, especially for scheduling meetings which fit with everybody's calendar";
// Tips
out.tips = {};
out.tips.lag = "The green icon in the upper right shows the quality of your internet connection to the CryptPad server.";
out.tips.shortcuts = "`ctrl+b`, `ctrl+i` and `ctrl+u` are quick shortcuts for bold, italic and underline.";
out.tips.indent = "In numbered and bulleted lists, you can use tab or shift+tab to quickly increase or decrease indentation.";
out.tips.title = "You can set the title of your pad by clicking the top center.";
out.tips.store = "Every time you visit a pad, if you're logged in it will be saved to your CryptDrive.";
out.tips.marker = "You can highlight text in a pad using the \"marker\" item in the styles dropdown menu.";
out.feedback_about = "If you're reading this, you were probably curious why CryptPad is requesting web pages when you perform certain actions";
out.feedback_privacy = "We care about your privacy, and at the same time we want CryptPad to be very easy to use. We use this file to figure out which UI features matter to our users, by requesting it along with a parameter specifying which action was taken.";
out.feedback_optout = "If you would like to opt out, visit <a href='/settings/'>your user settings page</a>, where you'll find a checkbox to enable or disable user feedback";
return out;
/*
* You can override the translation text using this file.
* The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js)
in a 'customize' directory (/customize/translations/messages.{LANG}.js).
* If you want to check all the existing translation keys, you can open the internal language file
but you should not change it directly (/common/translations/messages.{LANG}.js)
*/
define(['/common/translations/messages.pt-br.js'], function (Messages) {
// Replace the existing keys in your copied file here:
// Messages.button_newpad = "New Rich Text Document";
return Messages;
});

View File

@ -1,360 +1,14 @@
define(function () {
var out = {};
/*
* You can override the translation text using this file.
* The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js)
in a 'customize' directory (/customize/translations/messages.{LANG}.js).
* If you want to check all the existing translation keys, you can open the internal language file
but you should not change it directly (/common/translations/messages.{LANG}.js)
*/
define(['/common/translations/messages.ro.js'], function (Messages) {
// Replace the existing keys in your copied file here:
// Messages.button_newpad = "New Rich Text Document";
out.main_title = "CryptPad: Zero Knowledge, Colaborare în timp real";
out.main_slogan = "Puterea stă în cooperare - Colaborarea este cheia";
out.button_newpad = "Filă Text Nouă";
out.button_newcode = "Filă Cod Nouă";
out.button_newpoll = "Sondaj Nou";
out.button_newslide = "Prezentare Nouă";
out.button_newwhiteboard = "Fila Desen Nouă";
out.updated_0_common_connectionLost = "<b>Conexiunea la server este pierdută</b><br>Până la revenirea conexiunii, vei fi în modul citire";
out.common_connectionLost = out.updated_0_common_connectionLost;
out.websocketError = "Conexiune inexistentă către serverul websocket...";
out.typeError = "Această filă nu este compatibilă cu aplicația aleasă";
out.onLogout = "Nu mai ești autentificat, {0}apasă aici{1} să te autentifici<br>sau apasă <em>Escape</em>să accesezi fila în modul citire.";
out.wrongApp = "Momentan nu putem arăta conținutul sesiunii în timp real în fereastra ta. Te rugăm reîncarcă pagina.";
out.loading = "Încarcă...";
out.error = "Eroare";
out.saved = "Salvat";
out.synced = "Totul a fost salvat";
out.deleted = "Pad șters din CryptDrive-ul tău";
out.disconnected = "Deconectat";
out.synchronizing = "Se sincronizează";
out.reconnecting = "Reconectare...";
out.lag = "Decalaj";
out.readonly = "Mod citire";
out.anonymous = "Anonim";
out.yourself = "Tu";
out.anonymousUsers = "editori anonimi";
out.anonymousUser = "editor anonim";
out.users = "Utilizatori";
out.and = "Și";
out.viewer = "privitor";
out.viewers = "privitori";
out.editor = "editor";
out.editors = "editori";
out.language = "Limbă";
out.upgrade = "Actualizare";
out.upgradeTitle = "Actualizează-ți contul pentru a mări limita de stocare";
out.MB = "MB";
out.greenLight = "Totul funcționează corespunzător";
out.orangeLight = "Conexiunea lentă la internet îți poate afecta experiența";
out.redLight = "Ai fost deconectat de la sesiune";
out.pinLimitReached = "Ai atins limita de stocare";
out.pinLimitReachedAlert = "Ai atins limita de stocare. Noile pad-uri nu vor mai fi stocate în CryptDrive.<br>Pentru a rezolva această problemă, poți să nlături pad-uri din CryptDrive-ul tău (incluzând gunoiul) sau să subscrii la un pachet premium pentru a-ți extinde spațiul de stocare.";
out.pinLimitNotPinned = "Ai atins limita de stocare.<br>Acest pad nu va fi stocat n CryptDrive-ul tău.";
out.pinLimitDrive = "Ai atins limita de stocare.<br>Nu poți să creezi alte pad-uri.";
out.importButtonTitle = "Importă un pad dintr-un fișier local";
out.exportButtonTitle = "Exportă pad-ul acesta către un fișier local";
out.exportPrompt = "Cum ai vrea să îți denumești fișierul?";
out.changeNamePrompt = "Schimbă-ți numele (lasă necompletat dacă vrei să fii anonim): ";
out.user_rename = "Schimbă numele afișat";
out.user_displayName = "Nume afișat";
out.user_accountName = "Nume cont";
out.clickToEdit = "Click pentru editare";
out.forgetButtonTitle = "Mută acest pad la gunoi";
out.forgetPrompt = "Click-ul pe OK va muta acest pad la gunoi. Ești sigur?";
out.movedToTrash = "Acest pad a fost mutat la gunoi.<br><a href=\"/drive/\">Acesează-mi Drive-ul</a>";
out.shareButton = "Distribuie";
out.shareSuccess = "Link copiat în clipboard";
out.newButton = "Nou";
out.newButtonTitle = "Crează un nou pad";
out.saveTemplateButton = "Salvează ca șablon";
out.saveTemplatePrompt = "Alege un titlu pentru șablon";
out.templateSaved = "Șablon salvat!";
out.selectTemplate = "Selectează un șablon sau apasă escape";
out.presentButtonTitle = "Intră în modul de prezentare";
out.backgroundButtonTitle = "Schimbă culoarea de fundal din prezentare";
out.colorButtonTitle = "Schimbă culoarea textului în modul de prezentare";
out.printButton = "Printează (enter)";
out.printButtonTitle = "Printează-ți slide-urile sau exportă-le ca fișier PDF";
out.printOptions = "Opțiuni schemă";
out.printSlideNumber = "Afișează numărul slide-ului";
out.printDate = "Afișează data";
out.printTitle = "Afișează titlul pad-ului";
out.printCSS = "Reguli de stil personalizate (CSS):";
out.printTransition = "Permite tranziția animațiilor";
out.slideOptionsTitle = "Personalizează-ți slide-urile";
out.slideOptionsButton = "Salvează (enter)";
out.editShare = "Editează link-ul";
out.editShareTitle = "Copiază link-ul de editare în clipboard";
out.editOpen = "Deschide link-ul de editare într-o nouă filă";
out.editOpenTitle = "Deschide acest pad în modul de editare într-o nouă filă";
out.viewShare = "Link în modul citire";
out.viewShareTitle = "Copiază link-ul în modul de citire în clipboard";
out.viewOpen = "Deschide link-ul în modul de citire într-o filă nouă";
out.viewOpenTitle = "Deschide acest pad în modul de citire într-o nouă filă";
out.notifyJoined = "{0} s-au alăturat sesiunii colaborative";
out.notifyRenamed = "{0} e cunoscut ca {1}";
out.notifyLeft = "{0} au părăsit sesiunea colaborativă";
out.okButton = "OK (enter)";
out.cancel = "Anulează";
out.cancelButton = "Anulează (esc)";
out.historyButton = "Afișează istoricul documentului";
out.history_next = "Mergi la versiunea următoare";
out.history_prev = "Mergi la versiunea trecută";
out.history_goTo = "Mergi la sesiunea selectată";
out.history_close = "Înapoi";
out.history_closeTitle = "Închide istoricul";
out.history_restore = "Restabilește";
out.history_restoreTitle = "Restabilește versiunea selectată a documentului";
out.history_restorePrompt = "Ești sigur că vrei să înlocuiești versiunea curentă a documentului cu cea afișată?";
out.history_restoreDone = "Document restabilit";
out.history_version = "Versiune:";
out.poll_title = "Zero Knowledge Selector Dată";
out.poll_subtitle = "Zero Knowledge, <em>realtime</em> programare";
out.poll_p_save = "Setările tale sunt actualizate instant, așa că tu nu trebuie să salvezi.";
out.poll_p_encryption = "Tot conținutul tău este criptat ca doar persoanele cărora tu le dai link-ul să aibă acces. Nici serverul nu poate să vadă ce modifici.";
out.wizardLog = "Click pe butonul din dreapta sus pentru a te ntoarce la sondajul tău";
out.wizardTitle = "Folosește wizard-ul pentru a crea sondajul tău";
out.wizardConfirm = "Ești pregătit să adaugi aceste opțiuni la sondajul tău?";
out.poll_publish_button = "Publică";
out.poll_admin_button = "Admin";
out.poll_create_user = "Adaugă un nou utilizator";
out.poll_create_option = "Adaugă o nouă opțiune";
out.poll_commit = "Comite";
out.poll_closeWizardButton = "Închide wizard-ul";
out.poll_closeWizardButtonTitle = "Închide wizard-ul";
out.poll_wizardComputeButton = "Calculează Opțiunile";
out.poll_wizardClearButton = "Curăță Tabelul";
out.poll_wizardDescription = "Crează automat un număr de opțiuni întroducând orice număr de zile sau intervale orare";
out.poll_wizardAddDateButton = "+ Zi";
out.poll_wizardAddTimeButton = "+ Ore";
out.poll_optionPlaceholder = "Opțiune";
out.poll_userPlaceholder = "Numele tău";
out.poll_removeOption = "Ești sigur că vrei să îndepărtezi această opțiune?";
out.poll_removeUser = "Ești sigur că vrei să îndepărtezi aceast utilizator?";
out.poll_titleHint = "Titlu";
out.poll_descriptionHint = "Descrie sondajul, și apoi folosește butonul 'publică' când ai terminat. Orice utilizator care are link-ul poate modifica descrierea, dar descurajăm această practică.";
out.canvas_clear = "Curăță";
out.canvas_delete = "Curăță selecția";
out.canvas_disable = "Dezactivează modul desen";
out.canvas_enable = "Activează modul desen";
out.canvas_width = "Lățime";
out.canvas_opacity = "Opacitate";
out.fm_rootName = "Documente";
out.fm_trashName = "Gunoi";
out.fm_unsortedName = "Fișiere nesortate";
out.fm_filesDataName = "Toate fișierele";
out.fm_templateName = "Șabloane";
out.fm_searchName = "Caută";
out.fm_searchPlaceholder = "Caută...";
out.fm_newButton = "Nou";
out.fm_newButtonTitle = "Crează un nou pad sau folder";
out.fm_newFolder = "Folder nou";
out.fm_newFile = "Pad nou";
out.fm_folder = "Folder";
out.fm_folderName = "Numele folderului";
out.fm_numberOfFolders = "# de foldere";
out.fm_numberOfFiles = "# of files";
out.fm_fileName = "Nume filă";
out.fm_title = "Titlu";
out.fm_type = "Tip";
out.fm_lastAccess = "Ultima accesare";
out.fm_creation = "Creare";
out.fm_forbidden = "Acțiune interzisă";
out.fm_originalPath = "Ruta inițială";
out.fm_openParent = "Arată în folder";
out.fm_noname = "Document nedenumit";
out.fm_emptyTrashDialog = "Ești sigur că vrei să golești coșul de gunoi?";
out.fm_removeSeveralPermanentlyDialog = "Ești sigur că vrei să ștergi pentru totdeauna aceste {0} elemente din coșul de gunoi?";
out.fm_removePermanentlyDialog = "Ești sigur că vrei să ștergi acest element pentru totdeauna?";
out.fm_removeSeveralDialog = "Ești sigur că vrei să muți aceste {0} elemente la coșul de gunoi?";
out.fm_removeDialog = "Ești sigur că vrei să muți {0} la gunoi?";
out.fm_restoreDialog = "Ești sigur că vrei să restabilești {0} în locația trecută?";
out.fm_unknownFolderError = "Ultima locație vizitată sau cea selectată nu mai există. Deschidem fișierul părinte...";
out.fm_contextMenuError = "Nu putem deschide meniul de context pentru acest element. Dacă problema persistă, reîncarcă pagina.";
out.fm_selectError = "Nu putem selecta elementul vizat. Dacă problema persistă, reîncarcă pagina.";
out.fm_categoryError = "Nu putem deschide categoria selectată, afișează sursa.";
out.fm_info_root = "Crează câte foldere tip cuib ai nevoie pentru a-ți sorta fișierele.";
out.fm_info_unsorted = "Conține toate fișierele pe care le-ai vizitat și nu sunt sortate în \"Documente\" sau mutate în \"Gunoi\".";
out.fm_info_template = "Conține toate pad-urile stocate ca șabloane și pe care le poți refolosi atunci când creezi un nou pad.";
out.fm_info_trash = "Fișierele șterse din gunoi vor fi șterse și din \"Toate fișierele\", făcând imposibilă recuperarea fișierelor din managerul de fișiere.";
out.fm_info_allFiles = "Conține toate fișierele din \"Documente\", \"Nesortate\" și \"Gunoi\". Poți să muți sau să ștergi fișierele aici.";
out.fm_info_login = "Loghează-te";
out.fm_info_register = "Înscrie-te";
out.fm_info_anonymous = "Nu ești logat cu un cont valid așa că aceste pad-uri vor fi șterse (<a href=\"https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/\" target=\"_blank\">află de ce</a>). <a href=\"/register/\">Înscrie-te</a> sau <a href=\"/login/\">Loghează-te</a> pentru a le salva.";
out.fm_alert_backupUrl = "Link copie de rezervă pentru acest drive.<br> Este <strong>foarte recomandat</strong> să o păstrezi pentru tine.<br>Poți să o folosești pentru a recupera toate fișierele în cazul în care memoria browserului tău este șterge..<br>Oricine are linkul poate să editeze sau să îndepărteze toate fișierele din managerul tău de documente.<br>";
out.fm_alert_anonymous = "Salut, momentan folosești CryptPad în mod anonim. Este ok, doar că fișierele tale vor fi șterse după o perioadă de inactivitate. Am dezactivat caracteristicile avansate ale drive-ului pentru utilizatorii anonimi pentru a face clar faptul că stocare documentelor acolo nu este o metodă sigură. Poți să <a href=\"https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/\" target=\"_blank\">citești mai multe</a> despre motivarea noastră și despre ce de trebuie să te <a href=\"/register/\">Înregistrezi</a> si sa te <a href=\"/login/\">Loghezi</a>.";
out.fm_backup_title = "Link de backup";
out.fm_nameFile = "Cum ai vrea să numești fișierul?";
out.fc_newfolder = "Folder nou";
out.fc_rename = "Redenumește";
out.fc_open = "Deschide";
out.fc_open_ro = "Deschide (modul citire)";
out.fc_delete = "Șterge";
out.fc_restore = "Restaurează";
out.fc_remove = "Șterge permanent";
out.fc_empty = "Curăță coșul";
out.fc_prop = "Proprietăți";
out.fc_sizeInKilobytes = "Dimensiune n Kilobytes";
out.fo_moveUnsortedError = "Nu poți să muți un folder la lista de pad-uri nesortate";
out.fo_existingNameError = "Numele ales este deja folosit în acest director. Te rugăm să alegi altul.";
out.fo_moveFolderToChildError = "Nu poți să muți un folder într-unul dintre descendenții săi";
out.fo_unableToRestore = "Nu am reușit să restaurăm fișierul în locația de origine. Poți să ncerci să îl muți într-o nouă locație.";
out.fo_unavailableName = "Un fișier sau un folder cu același nume există deja în locația nouă. Redenumește elementul și încearcă din nou.";
out.login_login = "Loghează-te";
out.login_makeAPad = "Crează un pad în modul anonim";
out.login_nologin = "Răsfoiește pad-urile locale";
out.login_register = "Înscrie-te";
out.logoutButton = "Deloghează-te";
out.settingsButton = "Setări";
out.login_username = "Nume utilizator";
out.login_password = "Parolă";
out.login_confirm = "Confirmă parola";
out.login_remember = "Ține-mă minte";
out.login_hashing = "Încriptăm parola, o să mai dureze.";
out.login_hello = "Salut {0},";
out.login_helloNoName = "Salut,";
out.login_accessDrive = "Acesează-ți drive-ul";
out.login_orNoLogin = "sau";
out.login_noSuchUser = "Nume de utilizator sau parolă invalide. Încearcă din nou sau înscrie-te.";
out.login_invalUser = "Nume utilizator cerut";
out.login_invalPass = "Parolă cerută";
out.login_unhandledError = "O eroare neașteptată a avut loc emoticon_unhappy";
out.register_importRecent = "Importă istoricul pad-ului (Recomandat)";
out.register_acceptTerms = "Accept <a href='/terms.html'>termenii serviciului</a>";
out.register_passwordsDontMatch = "Parolele nu se potrivesc!";
out.register_mustAcceptTerms = "Trebuie să accepți termenii serviciului";
out.register_mustRememberPass = "Nu putem să îți resetăm parola dacă o uiți. Este foarte important să o ții minte! Bifează căsuța pentru a confirma.";
out.register_header = "Bine ai venit în CryptPad";
out.register_explanation = "<p>Hai să stabilim câteva lucruri, mai întâi</p><ul><li>Parola ta este cheia secretă care criptează toate pad-urile tale. Dacă pierzi/uiți parola nu există nici-o metodă prin care îți putem recupera datele.</li><li>Poți importa pad-uri care au fost vizionate recent în browser pentru a le avea în cont.</li><li>Dacă folosești un computer împărțit, trebuie să te deloghezi, închiderea taburilor nu este de ajuns.</li></ul>";
out.register_writtenPassword = "Mi-am notat numele de utilizator și parola, înaintează.";
out.register_cancel = "Întoarce-te";
out.register_warning = "Zero Knowledge înseamnă că noi nu îți putem recupera datele dacă îți pierzi parola.";
out.register_alreadyRegistered = "Acest user există deja, vrei să te loghezi?";
out.settings_title = "Setări";
out.settings_save = "Salvează";
out.settings_backupTitle = "Fă o copie de rezervă sau restaurează toate datele";
out.settings_backup = "Copie de rezervă";
out.settings_restore = "Restaurează";
out.settings_resetTitle = "Curăță-ți drive-ul";
out.settings_reset = "Îndepărtează toate fișierele și folderele din CryptPad-ul tău.";
out.settings_resetPrompt = "Această acțiune va indepărta toate pad-urile din drive-ul tău.<br>Ești sigur că vrei să continui?<br>Tastează “<em>Iubesc CryptPad</em>” pentru a confirma.";
out.settings_resetDone = "Drive-ul tău este acum gol!";
out.settings_resetError = "Text de verificare incorect. CryptPad-ul tău nu a fost schimbat.";
out.settings_resetTips = "Sfaturi în CryptDrive";
out.settings_resetTipsButton = "Resetează sfaturile disponibile în CryptDrive";
out.settings_resetTipsDone = "Toate sfaturile sunt vizibile din nou.";
out.settings_importTitle = "Importă pad-urile recente ale acestui browser n CryptDrive-ul meu";
out.settings_import = "Importă";
out.settings_importConfirm = "Ești sigur că vrei să imporți pad-urile recente ale acestui browser în contul tău de CryptDrive?";
out.settings_importDone = "Import complet";
out.settings_userFeedbackHint1 = "CryptPad oferă niște feedback foarte simplu serverului, pentru a ne informa cum putem să îți îmbunătățim experiența voastră.";
out.settings_userFeedbackHint2 = "Conținutul pad-ului tău nu va fi împărțit cu serverele.";
out.settings_userFeedback = "Activează feedback";
out.settings_anonymous = "Nu ești logat. Setările sunt specifice browser-ului.";
out.settings_publicSigningKey = "Cheia de semnătură publică";
out.settings_usage = "Uzaj";
out.settings_usageTitle = "Vezi dimensiunea totală a pad-urilor fixate în MB";
out.settings_pinningNotAvailable = "Pad-urile fixate sunt disponibile doar utilizatorilor înregistrați.";
out.settings_pinningError = "Ceva nu a funcționat";
out.settings_usageAmount = "Pad-urile tale fixate ocupă {0}MB";
out.settings_logoutEverywhereTitle = "Deloghează-te peste tot";
out.settings_logoutEverywhere = "Deloghează-te din toate sesiunile web";
out.settings_logoutEverywhereConfirm = "Ești sigur? Va trebui să te loghezi, din nou, pe toate device-urile tale.";
out.upload_serverError = "Eroare de server: fișierele tale nu pot fi încărcate la momentul acesta.";
out.upload_uploadPending = "Ai deja o încărcare în desfășurare. Anulezi și încarci noul fișier?";
out.upload_success = "Fișierul tău ({0}) a fost ncărcat și adăugat la drive-ul tău cu succes.";
out.main_p2 = "Acest proiect folosește <a href=\"http://ckeditor.com/\">CKEditor</a> Visual Editor, <a href=\"https://codemirror.net/\">CodeMirror</a>, și <a href=\"https://github.com/xwiki-contrib/chainpad\">ChainPad</a> un motor în timp real.";
out.main_howitworks_p1 = "CryptPad folosește o variantă a algoritmului de <a href=\"https://en.wikipedia.org/wiki/Operational_transformation\">Operational transformation</a> care este capabil să găsescă consens distribuit folosind <a href=\"https://bitcoin.org/bitcoin.pdf\">Nakamoto Blockchain</a>, o construcție popularizată de <a href=\"https://en.wikipedia.org/wiki/Bitcoin\">Bitcoin</a>. Astfel algoritmul poate evita nevoia ca serverul central să rezove conflicte, iar serverul nu este interesat de conținutul care este editat în pad.";
out.main_about_p2 = "Dacă ai orice fel de întrebare sau comentariu, poți să ne <a href=\"https://twitter.com/cryptpad\">dai un tweet</a>, semnalezi o problemă <a href=\"https://github.com/xwiki-labs/cryptpad/issues/\" title=\"index de probleme\">on github</a>, spui salut pe IRC (<a href=\"http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7\" title=\"freenode webchat\">irc.freenode.net</a>), sau <a href=\"research@xwiki.com\">trimiți un email</a>.";
out.main_info = "<h1>Colaborează în siguranță</h1><br> Dezvoltă-ți ideile împreună cu documentele partajate în timp ce tehnologia <strong>Zero Knowledge</strong> îți păstrează securitatea; chiar și de noi.";
out.main_howitworks = "Cum funcționează";
out.main_zeroKnowledge = "Zero Knowledge";
out.main_zeroKnowledge_p = "Nu trebuie să ne crezi că <em>nu ne uităm</em> la pad-urile tale, cu tehnologia revoluționară Zero Knowledge a CryptPad <em>nu putem</em>. Învață mai multe despre cum îți protejăm <a href=\"/privacy.html\" title='Intimitatea'>Intimitate și Securitate</a>.";
out.main_writeItDown = "Notează";
out.main_writeItDown_p = "Cele mai importante proiecte vin din idei mici. Notează-ți momentele de inspirație și ideile neașteptate pentru că nu știi niciodată care ar putea fi noua mare descoperire.";
out.main_share = "Partajează link-ul, partajează pad-ul";
out.main_share_p = "Dezvoltă-ți ideile împreună: organizează întâlniri eficiente, colaborează pe liste TODO și fă prezentări scurte cu toți prietenii tăi și device-urile tale.";
out.main_organize = "Organizează-te";
out.main_organize_p = "Cu CryptPad Drive, poți să stai cu ochii pe ce este important. Folderele îți permit să ții evidența proiectelor tale și să ai o viziune globală asupra evoluției lucrurilor.";
out.tryIt = "Testează!";
out.main_richText = "Rich Text editor";
out.main_richText_p = "Editează texte complexe în mod colaborativ cu Zero Knowledge în timp real. <a href=\"http://ckeditor.com\" target=\"_blank\">CkEditor</a> application.";
out.main_code = "Editor cod";
out.main_code_p = "Editează cod din softul tău, în mod colaborativ, cu Zero Knowledge în timp real.<a href=\"https://www.codemirror.net\" target=\"_blank\">CodeMirror</a> application.";
out.main_slide = "Editor slide-uri";
out.main_slide_p = "Crează-ți prezentări folosind sintaxa Markdown, și afișează-le în browser-ul tău.";
out.main_poll = "Sondaj";
out.main_poll_p = "Plănuiește întâlniri sau evenimente, sau votează pentru cea mai bună soluție pentru problema ta.";
out.main_drive = "CryptDrive";
out.footer_applications = "Aplicații";
out.footer_contact = "Contact";
out.footer_aboutUs = "Despre noi";
out.about = "Despre";
out.privacy = "Privacy";
out.contact = "Contact";
out.terms = "ToS";
out.blog = "Blog";
out.policy_title = "Politica de confidențialitate CryptPad";
out.policy_whatweknow = "Ce știm despre tine";
out.policy_whatweknow_p1 = "Ca o aplicație care este găzduită online, CryptPad are acces la metadatele expuse de protocolul HTTP. Asta include adresa IP-ului tău, și alte titluri HTTP care pot fi folosite ca să identifice un browser. Poți să vezi ce informații împărtășește browser-ul tău vizitând <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending\" title=\"what http headers is my browser sending\">WhatIsMyBrowser.com</a>.";
out.policy_whatweknow_p2 = "Folosim <a href=\"https://www.elastic.co/products/kibana\" target=\"_blank\" rel=\"noopener noreferrer\" title=\"platforma de analiză open source\">Kibana</a>, o platformă open source, pentru a afla mai multe despre utilizatorii noștri. Kibana ne spune despre cum ai găsit CryptPad, căutare directă, printr-un motor de căutare, sau prin recomandare de la un alt serviciu online ca Reddit sau Twitter.";
out.policy_howweuse = "Cum folosim ce aflăm";
out.policy_howweuse_p1 = "Folosim aceste informații pentru a lua decizii mai bune în promovarea CryptPad, prin evaluarea eforturilor trecute care au fost de succes. Informațiile despre locația ta ne ajută să aflăm dacă ar trebui să oferim suport pentru alte limbi, pe lângă engleză.";
out.policy_howweuse_p2 = "Informațiile despre browser-ul tău (dacă este bazat pe un sistem de operare desktop sau mobil) ne ajută să luăm decizii când prioritizăm viitoarele îmbunătățiri. Echipa noastră de dezvoltare este mică, și încercăm să facem alegeri care să îmbunătățească experiența câtor mai mulți utilizatori.";
out.policy_whatwetell = "Ce le spunem altora despre tine";
out.policy_whatwetell_p1 = "Nu furnizăm informațiile obținute terților, decât dacă ne este cerut în mod legal.";
out.policy_links = "Link-uri către alte site-uri";
out.policy_links_p1 = "Acest site conține link-uri către alte site-uri, incluzându-le pe cele produse de alte organizații. Nu suntem responsabili pentru practicile de intimitate sau pentru conținutul site-urilor externe. Ca regulă generală, link-urile către site-uri externe sunt deschise ntr-o fereastră noup, pentru a face clar faptul că părăsiți CryptPad.fr.";
out.policy_ads = "Reclame";
out.policy_ads_p1 = "Nu afișăm nici o formă de publicitate online, dar s-ar putea să atașăm link-uri către instituțiile care ne finanțează cerecetarea.";
out.policy_choices = "Ce alegeri ai";
out.policy_choices_open = "Codul nostru este open source, așa că tu ai mereu posibilitatea de a-ți găzdui propria instanță de CryptPad.";
out.policy_choices_vpn = "Dacă vrei să folosești instanța găzduită de noi, dar nu vrei să îți expui IP-ul, poți să îl protejezi folosind <a href=\"https://www.torproject.org/projects/torbrowser.html.en\" title=\"downloads from the Tor project\" target=\"_blank\" rel=\"noopener noreferrer\">Tor browser bundle</a>, sau <a href=\"https://riseup.net/en/vpn\" title=\"VPNs provided by Riseup\" target=\"_blank\" rel=\"noopener noreferrer\">VPN</a>.";
out.policy_choices_ads = "Dacă vrei doar să blochezi platforma noastră de analiză, poți folosi soluții de adblocking ca <a href=\"https://www.eff.org/privacybadger\" title=\"download privacy badger\" target=\"_blank\" rel=\"noopener noreferrer\">Privacy Badger</a>.";
out.tos_title = "CryptPad Termeni de Utilizare";
out.tos_legal = "Te rugăm să nu fii rău intenționat, abuziv, sau să faci orice ilegal.";
out.tos_availability = "Sperăm că o să găsești acest serviciu util, dar disponibilitatea sau performanța nu poate fi garantată. Te rugăm să îți exporți datele n mod regulat.";
out.tos_e2ee = "Conținutul CryptPad poate fi citit sau modificat de oricine care poate ghici sau obține fragmentul identificator al pad-ului. Recomandăm să folosești soluții de comunicare criptate end-to-end-encrypted (e2ee) pentru a partaja link-uri, evitând orice risc în cazul unei scurgeri de informații.";
out.tos_logs = "Metadatele oferite de browser-ul tău serverului ar putea fi înscrise în scopul de a menține serviciul.";
out.tos_3rdparties = "Nu oferim date personale terților, decât dacă ne sunt solicitate prin lege.";
out.bottom_france = "<a href=\"http://www.xwiki.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Realizat cu <img class=\"bottom-bar-heart\" src=\"/customize/heart.png\" alt=\"love\" /> n <img class=\"bottom-bar-fr\" src=\"/customize/fr.png\" alt=\"Franța\" /></a>";
out.bottom_support = "<a href=\"http://labs.xwiki.com/\" title=\"XWiki Labs\" target=\"_blank\" rel=\"noopener noreferrer\">Un proiect al <img src=\"/customize/logo-xwiki2.png\" alt=\"XWiki SAS\" class=\"bottom-bar-xwiki\"/> Labs Project </a> cu susținerea <a href=\"http://ng.open-paas.org/\" title=\"OpenPaaS::ng\" target=\"_blank\" rel=\"noopener noreferrer\"> <img src=\"/customize/openpaasng.png\" alt=\"OpenPaaS-ng\" class=\"bottom-bar-openpaas\" /></a>";
out.header_france = "<a href=\"http://www.xwiki.com/\" target=\"_blank\" rel=\"noopener noreferrer\">With <img class=\"bottom-bar-heart\" src=\"/customize/heart.png\" alt=\"love\" /> from <img class=\"bottom-bar-fr\" src=\"/customize/fr.png\" title=\"Franța\" alt=\"Franța\"/> by <img src=\"/customize/logo-xwiki.png\" alt=\"XWiki SAS\" class=\"bottom-bar-xwiki\"/></a>";
out.header_support = "<a href=\"http://ng.open-paas.org/\" title=\"OpenPaaS::ng\" target=\"_blank\" rel=\"noopener noreferrer\"> <img src=\"/customize/openpaasng.png\" alt=\"OpenPaaS-ng\" class=\"bottom-bar-openpaas\" /></a>";
out.header_logoTitle = "Mergi la pagina principală";
out.initialState = "<p>Acesta este&nbsp;<strong>CryptPad</strong>, editorul colaborativ bazat pe tehnologia Zero Knowledge în timp real. Totul este salvat pe măsură ce scrii.<br>Partajează link-ul către acest pad pentru a edita cu prieteni sau folosește <span class=\"fa fa-share-alt\"></span> butonul pentru a partaja <em>read-only link</em>&nbsp;permițând vizualizarea dar nu și editarea.</p>";
out.codeInitialState = "/*\n Acesta este editorul colaborativ de cod bazat pe tehnologia Zero Knowledge CryptPad.\n Ce scrii aici este criptat, așa că doar oamenii care au link-ul pot să-l acceseze.\n Poți să alegi ce limbaj de programare pus n evidență și schema de culori UI n dreapta sus.\n*/";
out.slideInitialState = "# CryptSlide\n1. Scrie-ți conținutul slide-urilor folosind sintaxa markdown\n - Află mai multe despre sintaxa markdown [aici](http://www.markdowntutorial.com/)\n2. Separă-ți slide-urile cu ---\n3. Click pe butonul \"Play\" pentru a vedea rezultatele - Slide-urile tale sunt actualizate în timp real.";
out.driveReadmeTitle = "Ce este CryptPad?";
out.readme_welcome = "Bine ai venit n CryptPad !";
out.readme_p1 = "Bine ai venit în CryptPad, acesta este locul unde îți poți lua notițe, singur sau cu prietenii.";
out.readme_p2 = "Acest pad o să îți ofere un scurt ghid în cum poți să folosești CryptPad pentru a lua notițe, a le ține organizate și a colabora pe ele.";
out.readme_cat1 = "Descoperă-ți CryptDrive-ul";
out.readme_cat1_l1 = "Crează un pad: În CryptDrive-ul tău, dă click {0} apoi {1} și poți să creezi un pad.";
out.readme_cat1_l2 = "Deschide pad-urile din CryptDrive-ul tău: doublu-click pe iconița unui pad pentru a-l deschide.";
out.readme_cat1_l3 = "Organizează-ți pad-urile: Când ești logat, orice pad accesezi va fi afișat ca în secțiunea {0} a drive-ului tău.";
out.readme_cat1_l3_l1 = "Poți să folosești funcția click and drag pentru a muta fișierele în folderele secțiunii {0} a drive-ului tău și pentru a crea noi foldere.";
out.readme_cat1_l3_l2 = "Ține minte să încerci click-dreapta pe iconițe pentru că există și meniuri adiționale.";
out.readme_cat1_l4 = "Pune pad-urile vechi în gunoi. Poți să folosești funcția click and drag pe pad-uri în categoria {0} la fel ca și în cazul folderelor.";
out.readme_cat2 = "Crează pad-uri ca un profesionist";
out.edit = "editează";
out.view = "vezi";
out.readme_cat2_l1 = "Butonul {0} din pad-ul tău dă accesul colaboratorilor tăi să {1} sau să {2} pad-ul.";
out.readme_cat2_l2 = "Schimbă titlul pad-ului dând click pe creion";
out.readme_cat3 = "Descoperă aplicațiile CryptPad";
out.readme_cat3_l1 = "Cu editorul de cod CryptPad, poți colabora pe cod ca Javascript și markdown ca HTML și Markdown";
out.readme_cat3_l2 = "Cu editorul de slide-uri CryptPad, poți să faci prezentări scurte folosind Markdown";
out.readme_cat3_l3 = "Cu CryptPoll poți să organizezi votări rapide, mai ales pentru a programa ntâlniri care se potrivesc calendarelor tuturor";
out.tips = { };
out.tips.lag = "Iconița verde din dreapta-sus arată calitatea conexiunii internetului tău la serverele CryptPad.";
out.tips.shortcuts = "`ctrl+b`, `ctrl+i` and `ctrl+u` sunt scurtături pentru bold, italic și underline.";
out.tips.indentare = "În listele cu bulină sau cele numerotate, poți folosi tab sau shift+tab pentru a mări sau micșora indentarea.";
out.tips.titlu = "Poți seta titlul pad-urilor tale prin click pe centru sus.";
out.tips.stocare = "De fiecare dată când vizitezi un pad, dacă ești logat va fi salvat pe CryptDrive-ul tău.";
out.tips.marker = "Poți sublinia text într-un pad folosind itemul \"marker\" n meniul de stiluri.";
out.feedback_about = "Dacă citești asta, probabil că ești curios de ce CryptPad cere pagini web atunci când întreprinzi anumite acțiuni";
out.feedback_privacy = "Ne pasă de intimitatea ta, si în același timp vrem să păstrăm CryptPad ușor de folosit. Folosim acest fișier pentru a ne da seama care beneficii UI contează cel mai mult pentru utilizatori, cerându-l alături de un parametru specific atunci când acțiunea se desfășoară";
out.feedback_optout = "Dacă vrei să ieși, vizitează <a href='/settings/'>setările de pe pagina ta de user</a>, unde vei găsi o căsuță pentru a activa sau dezactiva feedback-ul de la user";
return out;
return Messages;
});

View File

@ -1,530 +1,14 @@
define(function () {
var out = {};
// translations must set this key for their language to be available in
// the language dropdowns that are shown throughout Cryptpad's interface
out._languageName = 'Chinese';
out.main_title = "CryptPad: 零知識, 即時協作編寫";
out.main_slogan = "團結就是力量 - 合作是關鍵"; // TODO remove?
out.type = {};
out.type.pad = '富文本';
out.type.code = '編碼';
out.type.poll = '投票';
out.type.slide = '投影片簡報';
out.type.drive = '磁碟';
out.type.whiteboard = '白板';
out.type.file = '檔案';
out.type.media = '多媒體';
out.button_newpad = '富文件檔案';
out.button_newcode = '新代碼檔案';
out.button_newpoll = '新投票調查';
out.button_newslide = '新簡報';
out.button_newwhiteboard = '新白板';
// NOTE: We want to update the 'common_connectionLost' key.
// Please do not add a new 'updated_common_connectionLostAndInfo' but change directly the value of 'common_connectionLost'
out.updated_0_common_connectionLost = "<b>伺服器連線中斷</b><br>現在是唯讀狀態,直到連線恢復正常。";
out.common_connectionLost = out.updated_0_common_connectionLost;
out.websocketError = '無法連結上 websocket 伺服器...';
out.typeError = "這個編輯檔與所選的應用程式並不相容";
out.onLogout = '你已登出, {0}點擊這裏{1} 來登入<br>或按<em>Escape</em> 來以唯讀模型使用你的編輯檔案';
out.wrongApp = "無法在瀏覽器顯示即時期間的內容,請試著再重新載入本頁。";
out.loading = "載入中...";
out.error = "錯誤";
out.saved = "儲存";
out.synced = "所有資料已儲存好了";
out.deleted = "自 CryptDrive 刪除檔案";
out.disconnected = '已斷線';
out.synchronizing = '同步中';
out.reconnecting = '重新連結...';
out.lag = 'Lag';
out.readonly = '唯讀';
out.anonymous = "匿名";
out.yourself = "你自己";
out.anonymousUsers = "匿名的編輯群";
out.anonymousUser = "匿名的編輯群者";
out.users = "用戶";
out.and = "與";
out.viewer = "檢視者";
out.viewers = "檢視群";
out.editor = "編輯者";
out.editors = "編輯群";
out.language = "語言";
out.comingSoon = "即將上市...";
out.newVersion = '<b>CryptPad 已更新!</b><br>' +
'檢查最新版本有什麼新功能:<br>'+
'<a href="https://github.com/xwiki-labs/cryptpad/releases/tag/{0}" target="_blank">CryptPad新發佈記事 {0}</a>';
out.upgrade = "昇級";
out.upgradeTitle = "昇級帳戶以取得更多的儲存空間";
out.MB = "MB";
out.GB = "GB";
out.KB = "KB";
out.formattedMB = "{0} MB";
out.formattedGB = "{0} GB";
out.formattedKB = "{0} KB";
out.greenLight = "每件事都很順利";
out.orangeLight = "連線速度慢可能會影響用戶體驗";
out.redLight = "你這段期間的連線已中斷";
out.pinLimitReached = "你已達到儲存容量上限";
out.updated_0_pinLimitReachedAlert = "你已達到儲存容量上限,新檔案不會儲存到你的 CryptDrive.<br>" +
'要嘛你可以自 CryptDrive 移除原有文件或是 <a href="https://accounts.cryptpad.fr/#!on={0}" target="_blank">昇級到付費版</a>增加你的儲存容量。';
out.pinLimitReachedAlert = out.updated_0_pinLimitReachedAlert;
out.pinLimitNotPinned = "你已達到容量使用上限<br>"+
"這個檔案無法儲存到你的 CryptDrive.";
out.pinLimitDrive = "你已達到容量使用上限<br>" +
"你不能建立新的編輯檔案";
out.importButtonTitle = '從電腦上傳滙入檔案';
out.exportButtonTitle = '將這個檔案滙出到電腦';
out.exportPrompt = '你希望怎麼命名你的檔案?';
out.changeNamePrompt = '更換你的名稱(若留空白則會成為無名氏): ';
out.user_rename = "改變顯示名稱";
out.user_displayName = "顯示名稱";
out.user_accountName = "帳號名稱";
out.clickToEdit = "點擊以編輯";
out.forgetButtonTitle = '將這個檔案移置垃圾筒';
out.forgetPrompt = '點擊 OK 將把這個檔案移置垃圾筒,確定要這樣做嗎';
out.movedToTrash = '這個檔案已被移置垃圾筒<br><a href="/drive/">讀取我的雲端硬碟</a>';
out.shareButton = '分享';
out.shareSuccess = '複製連結到剪貼版';
out.newButton = '新';
out.newButtonTitle = '建立新的工作檔案';
out.saveTemplateButton = "存成模版";
out.saveTemplatePrompt = "為這個模版選一個標題";
out.templateSaved = "模版已儲存!";
out.selectTemplate = "選擇一個模版或是按 escape 跳出";
out.previewButtonTitle = "顯示或隱藏 Markdown 預覽模式";
out.presentButtonTitle = "輸入簡報模式";
out.backgroundButtonTitle = '改變簡報的顏色背景';
out.colorButtonTitle = '在簡報模式下改變文字顏色';
out.printButton = "列印 (enter)";
out.printButtonTitle = "列印投影片或滙出成 PDF 檔案";
out.printOptions = "版型選項";
out.printSlideNumber = "顯示投影片號碼";
out.printDate = "顯示日期";
out.printTitle = "顯示檔案標題";
out.printCSS = "自定風格規則 (CSS):";
out.printTransition = "啟用轉場動畫";
out.slideOptionsTitle = "自定你的投影片";
out.slideOptionsButton = "儲存 (enter)";
out.editShare = "編輯連結";
out.editShareTitle = "複製所編輯的連結到剪貼版";
out.editOpen = "在新分頁開啟連結編輯";
out.editOpenTitle = "在新分頁開啟這個檔案為編輯模式";
out.viewShare = "唯讀連結";
out.viewShareTitle = "複製唯讀的連結到剪貼版";
out.viewOpen = "在新分頁開啟唯讀連結";
out.viewOpenTitle = "在新分頁開啟這個檔案為唯讀模式";
out.notifyJoined = "{0} 已加入此協作期間";
out.notifyRenamed = "{0} 現在改名為 {1}";
out.notifyLeft = "{0} 已離開了這個協作期間";
out.okButton = 'OK (enter)';
out.cancel = "取消";
out.cancelButton = '取消 (esc)';
out.historyButton = "顯示文件歷史";
out.history_next = "到下一個版本";
out.history_prev = "到之前的版本";
out.history_goTo = "到所選擇的版本";
out.history_close = "回到";
out.history_closeTitle = "關閉歷史記錄";
out.history_restore = "重建";
out.history_restoreTitle = "將此文件重建到所挑選的版本";
out.history_restorePrompt = "確定要將這個展現的版本來取代現有版本嗎?";
out.history_restoreDone = "文件已重建";
out.history_version = "版本:";
// Polls
out.poll_title = "零知識日期挑選";
out.poll_subtitle = "零知識, <em>即時</em> 排程";
out.poll_p_save = "你的設定會立即更新, 因此從不需要按鍵儲存或擔心遺失。";
out.poll_p_encryption = "你所有幹入的資料都會予以加密,只有取得連結者才可以讀取它。即便是伺服器也不能看到你作了什麼變動。";
out.wizardLog = "點擊左上方的按鍵以回到你的調查";
out.wizardTitle = "使用精靈來建立調查投票";
out.wizardConfirm = "你真的要新增這些問題到你的調查中嗎?";
out.poll_publish_button = "發佈";
out.poll_admin_button = "管理者";
out.poll_create_user = "新增使用者";
out.poll_create_option = "新增選項";
out.poll_commit = "投入";
out.poll_closeWizardButton = "關閉協助精靈";
out.poll_closeWizardButtonTitle = "關閉協助精靈";
out.poll_wizardComputeButton = "計算最適化";
out.poll_wizardClearButton = "清除表格";
out.poll_wizardDescription = "透過輸入任何日期或時間分段,可自動建立一些選項";
out.poll_wizardAddDateButton = "+ 日期";
out.poll_wizardAddTimeButton = "+ 時間";
out.poll_optionPlaceholder = "選項";
out.poll_userPlaceholder = "你的名稱";
out.poll_removeOption = "確定要移除這個選項嗎?";
out.poll_removeUser = "確定要移除這位使用者嗎?";
out.poll_titleHint = "標題";
out.poll_descriptionHint = "請簡述這個調查目的,完成時使用「發佈鍵」。任何知道此調查連結者可以更改這裏的描述內容,但我們不鼓勵這麼做。.";
// Canvas
out.canvas_clear = "清除";
out.canvas_delete = "刪除所選";
out.canvas_disable = "取消繪圖";
out.canvas_enable = "啟動繪圖";
out.canvas_width = "寛度";
out.canvas_opacity = "透明度";
// File manager
out.fm_rootName = "根目錄";
out.fm_trashName = "垃圾桶";
out.fm_unsortedName = "未整理的檔案";
out.fm_filesDataName = "所有檔案";
out.fm_templateName = "模版";
out.fm_searchName = "搜尋";
out.fm_searchPlaceholder = "搜尋...";
out.fm_newButton = "新的";
out.fm_newButtonTitle = "建立新工作檔案或資料夾";
out.fm_newFolder = "新資料夾";
out.fm_newFile = "新工作檔案";
out.fm_folder = "資料夾";
out.fm_folderName = "資料夾名稱";
out.fm_numberOfFolders = "# 個資料夾";
out.fm_numberOfFiles = "# 檔案";
out.fm_fileName = "檔案名";
out.fm_title = "標題";
out.fm_type = "類型";
out.fm_lastAccess = "上回使用";
out.fm_creation = "創建";
out.fm_forbidden = "禁止的行為";
out.fm_originalPath = "原始路徑";
out.fm_openParent = "顯示在目錄夾中";
out.fm_noname = "無標題文件";
out.fm_emptyTrashDialog = "確定要清理垃圾筒嗎?";
out.fm_removeSeveralPermanentlyDialog = "確定要將這些 {0} 東西永自垃圾筒移除嗎?";
out.fm_removePermanentlyDialog = "你確定要永久地移除這些項目嗎?";
out.fm_removeSeveralDialog = "確定要將這些 {0} 東西移至垃圾筒嗎?";
out.fm_removeDialog = "確定要將移動 {0} 至垃圾筒嗎?";
out.fm_restoreDialog = "確定要重置 {0} 到它之前的位置嗎?";
out.fm_unknownFolderError = "所選或上回訪問的目錄不再存在了,正開啟上層目錄中...";
out.fm_contextMenuError = "無法在此元件下打開文本選單。如果這個問題一直發生,請試著重新載入此頁。";
out.fm_selectError = "無法選取目標的要素。如果這個問題一直發生,請試著重新載入此頁。";
out.fm_categoryError = "無法打開所選的類別,正在顯示根目錄。";
out.fm_info_root = "在此建立任何巢狀目錄夾以便於整理分類你的檔案。";
out.fm_info_unsorted = '包含所有你曾訪問過的檔案,其尚未被整理在 "根目錄" 或移到到"垃圾筒".'; // "My Documents" should match with the "out.fm_rootName" key, and "Trash" with "out.fm_trashName"
out.fm_info_template = '包含所有工作檔案已存成模版,便於讓你在建立新工作檔案時套用。';
out.updated_0_fm_info_trash = '清空垃圾筒好讓 CryptDrive 多出一些空間';
out.fm_info_trash = out.updated_0_fm_info_trash;
out.fm_info_allFiles = '包含在 "根目錄", "未整理的" 和 "垃圾筒" 裏的所有檔案。這裏你無法移動或移除檔案。'; // Same here
out.fm_info_anonymous = '你尚未登入,因此這些工作檔案可能會被刪除。 (<a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">了解原因</a>). ' +
'<a href="/register/">註冊</a>或<a href="/login/">登入</a>以便保留它們。';
out.fm_alert_backupUrl = "這個雲端硬碟的備份連結<br>" +
"<strong>高度建議</strong>把自己的 IP 資訊保留成只有自己知道<br>" +
"萬一瀏覽器記憶被消除,你可以用它來接收所有的檔案。<br>" +
"任何知道此連結的人可以編輯或移除你檔案管理底下的所有檔案。<br>";
out.fm_alert_anonymous = "嗨你好, 你目前正以匿名方式在使用 CryptPad , 這也沒問題,不過你的東西過一段時間沒動靜後,就會自動被刪除。 " +
"匿名的用戶我們也取消其進階功能,因為我們要明確地讓用戶知道,這裏 " +
'不是一個安全存放東西的地方。你可以 <a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">進一步了解 </a> 關於 ' +
'為何我們這樣作,以及為何你最好能夠<a href="/register/">註冊</a> 以及 <a href="/login/">登錄</a>使用。';
out.fm_backup_title = '備份連結';
out.fm_nameFile = '你想要如何來命名這個檔案呢?';
out.fm_error_cantPin = "內部伺服器出錯,請重新載入本頁並再試一次。";
// File - Context menu
out.fc_newfolder = "新資料夾";
out.fc_rename = "重新命名";
out.fc_open = "打開";
out.fc_open_ro = "打開 (唯讀)";
out.fc_delete = "刪除";
out.fc_restore = "重置";
out.fc_remove = "永久刪除";
out.fc_empty = "清理垃圾筒";
out.fc_prop = "Properties";
out.fc_sizeInKilobytes = "容量大小 (Kilobytes)";
// fileObject.js (logs)
out.fo_moveUnsortedError = "你不能移動資料夾到未整理的工作檔案清單";
out.fo_existingNameError = "名稱已被使用,請選擇其它名稱";
out.fo_moveFolderToChildError = "你不能移動資料夾到它的子資料夾底下";
out.fo_unableToRestore = "無法將這個檔案重置到原始的位置。你可以試著將它移動到其它新位置。";
out.fo_unavailableName = "在新位置裏同名的檔案或資料夾名稱已存在,請重新命名後再試看看。";
// login
out.login_login = "登入";
out.login_makeAPad = '匿名地建立一個工作檔案';
out.login_nologin = "瀏覽本地的工作檔案";
out.login_register = "註冊";
out.logoutButton = "登出";
out.settingsButton = "設定";
out.login_username = "用戶名";
out.login_password = "密碼";
out.login_confirm = "確認你的密碼";
out.login_remember = "記住我";
out.login_hashing = "散列你的密碼中,這要花上一點時間";
out.login_hello = 'Hello {0},'; // {0} is the username
out.login_helloNoName = 'Hello,';
out.login_accessDrive = '取用你的磁碟';
out.login_orNoLogin = '或';
out.login_noSuchUser = '無效的用戶名或密碼,請再試一次或重新註冊';
out.login_invalUser = '要求用戶名';
out.login_invalPass = '要求密碼';
out.login_unhandledError = '發生了未預期的錯誤 :(';
out.register_importRecent = "滙入檔案記錄 (建議)";
out.register_acceptTerms = "我同意 <a href='/terms.html'>服務條款</a>";
out.register_passwordsDontMatch = "密碼不相符!";
out.register_mustAcceptTerms = "你必須同意我們的服務條款。";
out.register_mustRememberPass = "如果你忘了密碼,我們也無法為你重置。因此務必自行好好記住! 請在勾選處勾選確認。";
out.register_header = "歡迎來到 CryptPad";
out.register_explanation = [
"<p>首先讓我們先了解幾件事</p>",
"<ul>",
"<li>你的密碼是你用來加密所有工作檔案的密鑰。一旦遺失它,我們也沒辦法幫你恢復你的資料。</li>",
"<li>你可以滙入近期在瀏覽器下檢視的工作檔案到你的雲端硬碟裏。</li>",
"<li>如果你使用的是公用分享電腦,你需要在完成工作後進行登出,只是關閉分頁是不夠的。</li>",
"</ul>"
].join('');
out.register_writtenPassword = "我已記下了我的用戶名和密碼,請繼續";
out.register_cancel = "回去";
out.register_warning = "零知識表示如果你遺失了密碼,我們也無法還原你的資料";
out.register_alreadyRegistered = "這名用戶己存在了,你要登入嗎?";
// Settings
out.settings_title = "設定";
out.settings_save = "儲存";
out.settings_backupTitle = "備份或重建你所有的資料";
out.settings_backup = "備份";
out.settings_restore = "重建";
out.settings_resetTitle = "清除你的雲端硬碟";
out.settings_reset = "從你的 CryptDrive 移除所有的檔案和資料夾";
out.settings_resetPrompt = "這個動作會自你的雲端硬碟中移除所有工作檔案<br>"+
"確定要繼續嗎?<br>" +
"輸入 “<em>I love CryptPad</em>” 來確認。";
out.settings_resetDone = "你的目錄現已清空!";
out.settings_resetError = "不正確的認證文字,你的 CryptDrive 並未更改。";
out.settings_resetTips = "使用 CryptDrive 的竅門";
out.settings_resetTipsButton = "在 CryptDrive 下重置可用的訣竅";
out.settings_resetTipsDone = "所有的訣竅現在都可再次看到了。";
out.settings_importTitle = "滙入這個瀏覽器近期的工作檔案到我的 CryptDrive";
out.settings_import = "滙入";
out.settings_importConfirm = "確定要從這個瀏覽器滙入近期的工作檔案到你的 CryptDrive ";
out.settings_importDone = "滙入完成";
out.settings_userFeedbackHint1 = "CryptPad 會提供一些基本的反饋到伺服器,以讓我們知道如何改善用戶體驗。";
out.settings_userFeedbackHint2 = "你的工作檔案內容絕不會被分享到伺服器";
out.settings_userFeedback = "啟用用戶反饋功能";
out.settings_anonymous = "你尚未登入,在此瀏覽器上進行特別設定。";
out.settings_publicSigningKey = "公開金鑰簽署";
out.settings_usage = "用法";
out.settings_usageTitle = "查看所有置頂的工作檔案所佔的容量";
out.settings_pinningNotAvailable = "工作檔案置頂功能只開放給已註冊用戶";
out.settings_pinningError = "有點不對勁";
out.settings_usageAmount = "你置頂的工作檔案佔了 {0}MB";
out.settings_logoutEverywhereTitle = "自所有地點登出";
out.settings_logoutEverywhere = "自所有其它的網頁期間登出";
out.settings_logoutEverywhereConfirm = "你確定嗎?你將需要登入到所有用到設置。";
out.upload_serverError = "伺服器出錯:本次無法上傳你的檔案";
out.upload_uploadPending = "你欲上傳檔案正在傳輸中,要取消並上傳新檔案嗎?";
out.upload_success = "你的檔案 ({0}) 已成功地上傳並放入到你的網路磁碟中。";
out.upload_notEnoughSpace = "你的 CryptDrive 無足夠空間來存放這個檔案。";
out.upload_tooLarge = "此檔案超過了上傳單一檔案可允許的容量上限。";
out.upload_choose = "選擇一個檔案";
out.upload_pending = "待處理";
out.upload_cancelled = "已取消的";
out.upload_name = "檔案名";
out.upload_size = "大小";
out.upload_progress = "進度";
out.download_button = "解密 & 下載";
// general warnings
out.warn_notPinned = "這個工作檔案並不在任何人的 CryptDrive 裏,它將在 3 個月到期後刪除。 <a href='/about.html#pinning'>進一步了解...</a>";
// index.html
//about.html
out.main_p2 = '本專案使用 <a href="http://ckeditor.com/">CKEditor</a> 視覺編輯器, <a href="https://codemirror.net/">CodeMirror</a>, 以及 <a href="https://github.com/xwiki-contrib/chainpad">ChainPad</a> 即時引擊。';
out.main_howitworks_p1 = 'CryptPad 應用一種變體的 <a href="https://en.wikipedia.org/wiki/Operational_transformation">操作型變換 Operational transformation</a> 演算法,它利用<a href="https://bitcoin.org/bitcoin.pdf">Nakamoto Blockchain</a>來找到分散的共識, Nakamoto Blockchain 是一種建構當前流行的<a href="https://en.wikipedia.org/wiki/Bitcoin">比特幣</a>。這套演算法可避免需要一個中央的伺服器來解析操作型變換編輯衝突,而無須處理解析衝突,伺服器並不知道哪一個檔案被編輯。';
// contact.html
out.main_about_p2 = '若有任何問題和建議, 可以在<a href="https://twitter.com/cryptpad">tweet us</a>, <a href="https://github.com/xwiki-labs/cryptpad/issues/" title="our issue tracker">github</a>提出問題, 或是來到 irc (<a href="http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7" title="freenode webchat">irc.freenode.net</a>)打聲招呼, 再或者 <a href="mailto:research@xwiki.com">寄封電郵給我們</a>.';
out.main_info = "<h1>Collaborate in Confidence</h1><br> 利用共同享文件發嚮點子,透過 <strong>零知識 </strong> 科技確保隱私安全; 對任何網路服務商都要加以提防。";
out.main_howitworks = '它如何運作';
out.main_zeroKnowledge = '零知識';
out.main_zeroKnowledge_p = "你不必相信我們所說的<em>並不會</em> 察看你的檔案, CryptPad 革命性的零知識技術讓我們 <em>真的不能看到</em>。 進一步了解在這裏,我們如何保護用戶的 <a href=\"/privacy.html\" title='Privacy'>隱私和安全</a>。";
out.main_writeItDown = '寫下它';
out.main_writeItDown_p = "偉大的專案來自不起眼的小點子。記下靈感與點子的瞬間,因為你從不會知道哪個會帶來重大突破。";
out.main_share = '分享連結, 分享工作檔案';
out.main_share_p = "一起來發響想法點子: 在任何設備上,與朋友一起執行有效率的會議, 協作待辦清單與快速製作簡報。";
out.main_organize = 'Get organized';
out.main_organize_p = "利用 CryptPad 空間, 你可以保留看管重要的東西。資料夾讓你可以追踪專案和全盤了解事情的走向狀況。";
out.tryIt = 'Try it out!';
out.main_richText = '富文字編輯器';
out.main_richText_p = '利用我們的即時零知識技術,集體協作地編輯富文本檔案 <a href="http://ckeditor.com" target="_blank">CkEditor</a> 應用程式application.';
out.main_code = '代碼編輯器';
out.main_code_p = '利用我們的即時零知識技術,集體協作地編輯程式代碼 <a href="https://www.codemirror.net" target="_blank">CodeMirror</a> 應用程式。';
out.main_slide = '投影片編輯器';
out.main_slide_p = '使用 Markdown 語法來建立投影片,並利用瀏覽器來展示投影片。';
out.main_poll = '調查';
out.main_poll_p = '規劃會議或活動,或是為問題舉行投最佳方案的投票。';
out.main_drive = 'CryptDrive';
out.footer_applications = "應用程式";
out.footer_contact = "聯繫";
out.footer_aboutUs = "關於 Cryptpad";
out.about = "關於";
out.privacy = "隱私";
out.contact = "聯繫";
out.terms = "服務條款";
out.blog = "Blog";
// privacy.html
out.policy_title = 'CryptPad 隱私政策';
out.policy_whatweknow = '我們會知道哪些關於你的資料';
out.policy_whatweknow_p1 = '作為一個網頁上的應用程式, CryptPad 可以接取 HTTP 協議所曝露的元數據。 這包括你的 IP 地址、各式其它的 HTTP 標頭,其用於識別你特定的瀏覽器。 你可以訪問 <a target="_blank" rel="noopener noreferrer" href="https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending" title="what http headers is my browser sending">WhatIsMyBrowser.com</a>這個網站,知道你的瀏覽器分享了哪些資訊。';
out.policy_whatweknow_p2 = '我們使用 <a href="https://www.elastic.co/products/kibana" target="_blank" rel="noopener noreferrer" title="open source analytics platform">Kibana</a>, 它是一個開源的流量數據分析平台, 以更了解用戶。Kibana 讓我們知道你是如何地發現 CryptPad, 是透過直接接入、攑搜尋引擊或是其它網站的介紹如 Reddit 和 Twitter。';
out.policy_howweuse = '我們如何利用我們知道的東西';
out.policy_howweuse_p1 = '我們利用這些資訊評估過去成功的效果,以更佳地決定如何推廣 CryptPad。有關你地理位置的資訊讓我們知道是否該提供英語之外的語言版本支援';
out.policy_howweuse_p2 = "有關你的瀏覽器資訊 (是桌面還是手機操作系統) 有助於讓我們決定要優先哪些功能改善。我們開發團隊人很少,我們試著挑選盡可能地提昇更多用戶的使用體驗。";
out.policy_whatwetell = '我們可以告訴別人關於你的哪些資料';
out.policy_whatwetell_p1 = '我們不會給第三人我們所收集的資訊,除非被依法要求配合。';
out.policy_links = '其它網站連結';
out.policy_links_p1 = '本站含有其它網站的連結包括其它組織的産品。我們無法對這些隱私實踐或任何本站以外的內容負責。一般而言連到外站的連結會另啟新視窗以明確讓你知道已離開了CryptPad.fr.';
out.policy_ads = '廣告';
out.policy_ads_p1 = '我們不會放置任何線上廣告,但會提供一些資助我們研究的機構與團體的網址連結';
out.policy_choices = '你有的選擇';
out.policy_choices_open = '我們的代碼是開放的,你可以選擇自行在自己的機器上來架設自己的 CryptPad.';
out.policy_choices_vpn = '如果你要使用我們架設的服務, 但不希望曝露自己的 IP 地址, 你可以利用<a href="https://www.torproject.org/projects/torbrowser.html.en" title="downloads from the Tor project" target="_blank" rel="noopener noreferrer">Tor 瀏覽器套件</a>來保護隱藏 IP 地址, 或是使用 <a href="https://riseup.net/en/vpn" title="VPNs provided by Riseup" target="_blank" rel="noopener noreferrer">VPN</a>。';
out.policy_choices_ads = '如果你只是想要封鎖我們的數據分析器, 你可以使用廣告封鎖工具如 <a hre="https://www.eff.org/privacybadger" title="download privacy badger" target="_blank" rel="noopener noreferrer">Privacy Badger</a>.';
// terms.html
out.tos_title = "CryptPad 服務條款";
out.tos_legal = "請不要惡意、濫用或從事非法活動。";
out.tos_availability = "希望你覺得我們的産品與服務對你有所幫助, 但我們並不能一直百分百保證它的表現穩定與可得性。請記得定期滙出你的資料。";
out.tos_e2ee = "CryptPad 的內容可以被任何猜出或取得工作檔案分段識別碼的人讀取與修改。我們建議你使用端對端加密 (e2ee) 訊息技術來分享工作檔案連結 以及假設如果一旦連結外漏不會背上任何責任。";
out.tos_logs = "你的瀏覽器提供給伺服器的元數據,可能會因為維護本服務之效能而被收集記錄。";
out.tos_3rdparties = "除非法令要求,我們不會提供任何個人資料給第三方。";
// BottomBar.html
out.bottom_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Made with <img class="bottom-bar-heart" src="/customize/heart.png" alt="love" /> in <img class="bottom-bar-fr" src="/customize/fr.png" alt="France" /></a>';
out.bottom_support = '<a href="http://labs.xwiki.com/" title="XWiki Labs" target="_blank" rel="noopener noreferrer">An <img src="/customize/logo-xwiki2.png" alt="XWiki SAS" class="bottom-bar-xwiki"/> Labs Project </a> with the support of <a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
// Header.html
out.header_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">With <img class="bottom-bar-heart" src="/customize/heart.png" alt="love" /> from <img class="bottom-bar-fr" src="/customize/fr.png" title="France" alt="France"/> by <img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
out.header_support = '<a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
out.header_logoTitle = '回到主頁';
// Initial states
out.initialState = [
'<p>',
'這是&nbsp;<strong>CryptPad</strong>, 零知識即時協作編輯平台,當你輸入時一切已即存好。',
'<br>',
'分享這個工作檔案的網址連結給友人或是使用、 <span class="fa fa-share-alt"></span> 按鈕分享<em>唯讀的連結</em>&nbsp;其只能看不能編寫。',
'</p>'
].join('');
out.codeInitialState = [
'# CryptPad 零知識即時協作代碼編輯平台\n',
'\n',
'* 你所輸入的東西會予以加密,僅有知道此網頁連結者可以接取這份文件。\n',
'* 你可以在右上角選擇欲編寫的程式語言以及樣版配色風格。'
].join('');
out.slideInitialState = [
'# CryptSlide\n',
'1. 使用 markdown 語法來寫下你的投影片內容\n',
' - 進一步學習 markdown 語法 [here](http://www.markdowntutorial.com/)\n',
'2. 利用 --- 來區隔不同的投影片\n',
'3. 點擊下方 "Play" 鍵來查看成果',
' - 你的投影片會即時更新'
].join('');
// Readme
out.driveReadmeTitle = "什麼是 CryptPad?";
out.readme_welcome = "歡迎來到 CryptPad !";
out.readme_p1 = "歡迎來到 CryptPad, 這裏你可以獨自作個人筆記或是和別人共享協作。";
out.readme_p2 = "這個工作檔案可以讓你快速地了解如何使用 CryptPad 作筆記,有效地整理管理文件工作檔案。";
out.readme_cat1 = "認識如何使用 CryptDrive";
out.readme_cat1_l1 = "建立一個工作檔案: 在 CryptDrive 底下, 點擊 {0} 然後 {1} 這樣就可以建立一個新的工作檔案。"; // 0: New, 1: Rich Text
out.readme_cat1_l2 = "從 CryptDrive 開啟工作檔案: 雙擊工作檔案的圖示來開啟它。";
out.readme_cat1_l3 = "分類你的工作檔案:登入之後,每一個你能接取使用的工作檔案會顯示在你雲端硬碟中的 {0} 部份。"; // 0: Unsorted files
out.readme_cat1_l3_l1 = "你可以點擊或是拉曳檔案到雲端硬碟 {0} 區,新增資料夾。"; // 0: Documents
out.readme_cat1_l3_l2 = "記得試著點擊圖示,以顯示更多的選項功能。";
out.readme_cat1_l4 = "把舊的工作檔案放到垃圾筒:點擊或是拉曳檔案到 {0} 如同把它們拉到文件目錄夾一樣的方法。"; // 0: Trash
out.readme_cat2 = "像個專業人士來編寫你的工作檔案";
out.edit = "編輯";
out.view = "檢視";
out.readme_cat2_l1 = "在工作檔案下的 {0} 按鍵可讓其它的協作者接取 {1} 或是 {2} 工作檔案"; // 0: Share, 1: edit, 2: view
out.readme_cat2_l2 = "若要更改工作檔案的名稱,只要點擊右上的鉛筆圖示即可";
out.readme_cat3 = "發現其它的 CryptPad 應用";
out.readme_cat3_l1 = "使用 CryptPad 代碼編輯器,你可以和其它人協作各種程式碼,如 Javascript、 markdown、 HTML 等等。";
out.readme_cat3_l2 = "使用 CryptPad 投影片編輯功能,你可以使用 Markdown 快速製作簡報檔。";
out.readme_cat3_l3 = "利用 CryptPoll 你可以快速作個線上調查,尤其是調查每個人有空的會議時間。";
// Tips
out.tips = {};
out.tips.lag = "右上角的綠色圖標顯示你連線至 CryptPad 伺服器的連線品質。";
out.tips.shortcuts = "`ctrl+b`, `ctrl+i` 和 `ctrl+u` 分別是粗體字、斜體、與加底線用法的快速鍵。";
out.tips.indent = "要使用數字以及符號列表, 可使用 tab 或 shift+tab 快速地增加或滅少縮排指令。";
out.tips.title = "點擊正上方來設定工作檔案的標題。";
out.tips.store = "每一回你造訪一個工作檔案, 如果是登入狀態,則這些檔案會自動儲存到你的 CryptDrive.";
out.tips.marker = "在格式下拉選單中使用 \"marker\" 可以標注反亮文字.";
out.feedback_about = "如果你讀了這裏,也許會好奇為何當你執行某些動作時 CryptPad 會請求網頁資訊。";
out.feedback_privacy = "我們注重你的隱私,同時也要讓 CryptPad 容易使用。我們利用這個檔案來了解哪一種介面設計為用戶所重視,透過它來請求特別的功能參數。";
out.feedback_optout = "如果欲退出客戶資料收集, 請到 <a href='/settings/'>用戶設定頁</a>, 可以找到勾選項目來啟用或關閉用戶回饋功能。";
return out;
/*
* You can override the translation text using this file.
* The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js)
in a 'customize' directory (/customize/translations/messages.{LANG}.js).
* If you want to check all the existing translation keys, you can open the internal language file
but you should not change it directly (/common/translations/messages.{LANG}.js)
*/
define(['/common/translations/messages.zh.js'], function (Messages) {
// Replace the existing keys in your copied file here:
// Messages.button_newpad = "New Rich Text Document";
return Messages;
});

View File

@ -1,7 +1,7 @@
{
"name": "cryptpad",
"description": "realtime collaborative visual editor with zero knowlege server",
"version": "2.6.0",
"version": "2.14.0",
"license": "AGPL-3.0+",
"repository": {
"type": "git",

View File

@ -177,7 +177,7 @@ app.get('/api/config', function(req, res){
httpUnsafeOrigin: config.httpUnsafeOrigin,
}, null, '\t'),
'obj.httpSafeOrigin = ' + (function () {
if (config.httpSafeOrigin) { return config.httpSafeOrigin; }
if (config.httpSafeOrigin) { return '"' + config.httpSafeOrigin + '"'; }
if (config.httpSafePort) {
return "(function () { return window.location.origin.replace(/\:[0-9]+$/, ':" +
config.httpSafePort + "'); }())";

View File

@ -27,6 +27,53 @@ define([
sessionStorage[Constants.userHashKey];
var proxy;
var whenReady = function (cb) {
if (proxy) { return void cb(); }
console.log('CryptPad not ready...');
setTimeout(function () {
whenReady(cb);
}, 100);
};
$(window).on("message", function (jqe) {
var evt = jqe.originalEvent;
var data = JSON.parse(evt.data);
var domain = evt.origin;
var srcWindow = evt.source;
var ret = { txid: data.txid };
console.log('CP receiving', data);
if (data.cmd === 'PING') {
ret.res = 'PONG';
} else if (data.cmd === 'SIGN') {
if (!AUTHORIZED_DOMAINS.filter(function (x) { return x.test(domain); }).length) {
ret.error = "UNAUTH_DOMAIN";
} else if (!LocalStore.isLoggedIn()) {
ret.error = "NOT_LOGGED_IN";
} else {
return void whenReady(function () {
var sig = signMsg(data.data, proxy.edPrivate);
ret.res = {
uname: proxy.login_name,
edPublic: proxy.edPublic,
sig: sig
};
srcWindow.postMessage(JSON.stringify(ret), domain);
});
}
} else if (data.cmd === 'UPDATE_LIMIT') {
return void whenReady(function () {
Cryptpad.updatePinLimit(function (e, limit, plan, note) {
ret.res = [limit, plan, note];
srcWindow.postMessage(JSON.stringify(ret), domain);
});
});
} else {
ret.error = "UNKNOWN_CMD";
}
srcWindow.postMessage(JSON.stringify(ret), domain);
});
nThen(function (waitFor) {
Cryptpad.ready(waitFor());
}).nThen(function (waitFor) {
@ -40,36 +87,5 @@ define([
window.drive = proxy['drive'];
Test.passed();
});
$(window).on("message", function (jqe) {
var evt = jqe.originalEvent;
var data = JSON.parse(evt.data);
var domain = evt.origin;
var srcWindow = evt.source;
var ret = { txid: data.txid };
if (data.cmd === 'PING') {
ret.res = 'PONG';
} else if (data.cmd === 'SIGN') {
if (!AUTHORIZED_DOMAINS.filter(function (x) { return x.test(domain); }).length) {
ret.error = "UNAUTH_DOMAIN";
} else if (!LocalStore.isLoggedIn()) {
ret.error = "NOT_LOGGED_IN";
} else {
var sig = signMsg(data.data, proxy.edPrivate);
ret.res = {
uname: proxy.login_name,
edPublic: proxy.edPublic,
sig: sig
};
}
} else if (data.cmd === 'UPDATE_LIMIT') {
return Cryptpad.updatePinLimit(function (e, limit, plan, note) {
ret.res = [limit, plan, note];
srcWindow.postMessage(JSON.stringify(ret), domain);
});
} else {
ret.error = "UNKNOWN_CMD";
}
srcWindow.postMessage(JSON.stringify(ret), domain);
});
});
});

View File

@ -9,6 +9,12 @@ define(['/api/config'], function (ApiConfig) {
window.alert('The bounce application must only be used with a valid href to visit');
return;
}
if (bounceTo.indexOf('javascript:') === 0 || // jshint ignore:line
bounceTo.indexOf('vbscript:') === 0 || // jshint ignore:line
bounceTo.indexOf('data:') === 0) {
window.alert('Illegal bounce URL');
return;
}
window.opener = null;
window.location.href = bounceTo;
});

View File

@ -19,17 +19,16 @@
flex-flow: column;
height: 100%;
min-height: 100%;
width: 50%;
min-width: 20%;
max-width: 80%;
resize: horizontal;
overflow: hidden;
width: 50%;
&.cp-app-code-fullpage {
max-width: 100%;
resize: none;
flex: 1;
}
}
.CodeMirror {
flex: 1;
@ -51,9 +50,13 @@
#cp-app-code-container { display: none; }
#cp-app-code-preview { border: 0; }
}
&.cp-chat-visible {
#cp-app-code-container {
width: 35%;
}
}
}
#cp-app-code-preview {
flex: 1;
padding: 5px 20px;
overflow: auto;
display: inline-block;
@ -63,6 +66,7 @@
font-family: Calibri,Ubuntu,sans-serif;
word-wrap: break-word;
position: relative;
flex: 1;
media-tag {
* {
max-width:100%;
@ -120,5 +124,12 @@
display: none !important;
}
}
#cp-app-code-print {
position: relative;
display: none;
margin: 1em auto;
.markdown_preformatted-code;
.markdown_gfm-table(black);
}
}

17
www/code/export.js Normal file
View File

@ -0,0 +1,17 @@
// This file is used when a user tries to export the entire CryptDrive.
// Pads from the code app will be exported using this format instead of plain text.
define([
'/common/sframe-common-codemirror.js',
], function (SFCodeMirror) {
var module = {};
module.main = function (userDoc, cb) {
var mode = userDoc.highlightMode || 'gfm';
var content = userDoc.content;
module.type = SFCodeMirror.getContentExtension(mode);
cb(SFCodeMirror.fileExporter(content));
};
return module;
});

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html class="cp-app-noscroll">
<html class="cp-app-noscroll cp-app-print">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script async data-bootload="/code/inner.js" data-main="/common/sframe-boot.js?ver=1.6" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
@ -17,6 +17,7 @@
</div>
<div id="cp-app-code-preview">
<div id="cp-app-code-preview-content"></div>
<div id="cp-app-code-print"></div>
</div>
</div>
</body>

View File

@ -8,6 +8,8 @@ define([
'/common/common-util.js',
'/common/common-hash.js',
'/common/modes.js',
'/common/visible.js',
'/common/TypingTests.js',
'/customize/messages.js',
'cm/lib/codemirror',
@ -49,6 +51,8 @@ define([
Util,
Hash,
Modes,
Visible,
TypingTest,
Messages,
CMeditor)
{
@ -66,6 +70,16 @@ define([
'xml',
]);
var mkPrintButton = function (framework, $content, $print) {
var $printButton = framework._.sfCommon.createButton('print', true);
$printButton.click(function () {
$print.html($content.html());
window.focus();
window.print();
framework.feedback('PRINT_CODE');
});
framework._.toolbar.$drawer.append($printButton);
};
var mkMarkdownTb = function (editor, framework) {
var $codeMirrorContainer = $('#cp-app-code-container');
var markdownTb = framework._.sfCommon.createMarkdownToolbar(editor);
@ -222,6 +236,12 @@ define([
}
});
Visible.onChange(function (visible) {
if (visible) {
drawPreview();
}
});
return {
forceDraw: forceDrawPreview,
draw: drawPreview,
@ -230,30 +250,6 @@ define([
};
};
var mkIndentSettings = function (editor, metadataMgr) {
var setIndentation = function (units, useTabs) {
if (typeof(units) !== 'number') { return; }
editor.setOption('indentUnit', units);
editor.setOption('tabSize', units);
editor.setOption('indentWithTabs', useTabs);
};
var indentKey = 'indentUnit';
var useTabsKey = 'indentWithTabs';
var updateIndentSettings = function () {
if (!metadataMgr) { return; }
var data = metadataMgr.getPrivateData().settings;
data = data.codemirror || {};
var indentUnit = data[indentKey];
var useTabs = data[useTabsKey];
setIndentation(
typeof(indentUnit) === 'number'? indentUnit: 2,
typeof(useTabs) === 'boolean'? useTabs: false);
};
metadataMgr.onChangeLazy(updateIndentSettings);
updateIndentSettings();
};
var mkFilePicker = function (framework, editor, evModeChange) {
evModeChange.reg(function (mode) {
if (MEDIA_TAG_MODES.indexOf(mode) !== -1) {
@ -279,13 +275,18 @@ define([
var previewPane = mkPreviewPane(editor, CodeMirror, framework, isPresentMode);
var markdownTb = mkMarkdownTb(editor, framework);
var $print = $('#cp-app-code-print');
var $content = $('#cp-app-code-preview-content');
mkPrintButton(framework, $content, $print);
mkHelpMenu(framework);
var evModeChange = Util.mkEvent();
evModeChange.reg(previewPane.modeChange);
evModeChange.reg(markdownTb.modeChange);
mkIndentSettings(editor, framework._.cpNfInner.metadataMgr);
CodeMirror.mkIndentSettings(framework._.cpNfInner.metadataMgr);
CodeMirror.init(framework.localChange, framework._.title, framework._.toolbar);
mkFilePicker(framework, editor, evModeChange);
@ -315,6 +316,13 @@ define([
return content;
});
framework.onCursorUpdate(CodeMirror.setRemoteCursor);
framework.setCursorGetter(CodeMirror.getCursor);
editor.on('cursorActivity', function () {
if (editor._noCursorUpdate) { return; }
framework.updateCursor();
});
framework.onEditableChange(function () {
editor.setOption('readOnly', framework.isLocked() || framework.isReadOnly());
});
@ -361,6 +369,12 @@ define([
editor.on('change', framework.localChange);
framework.start();
window.easyTest = function () {
var test = TypingTest.testCode(editor);
return test;
};
};
var getThumbnailContainer = function () {

View File

@ -56,8 +56,49 @@ define(function () {
};
};
var testPad = function (editor, onLocal) {
var i = 0,
input = " The quick red fox jumps over the lazy brown dog.",
l = input.length,
interval;
var cancel = function () {
if (interval) { interval.cancel(); }
};
interval = setRandomizedInterval(function () {
editor.insertText(input.charAt(i));
onLocal();
i = (i + 1) % l;
}, 200, 50);
return {
cancel: cancel
};
};
var testCode = function (editor) {
var i = 0,
input = " The quick red fox jumps over the lazy brown dog.",
l = input.length,
interval;
var cancel = function () {
if (interval) { interval.cancel(); }
};
interval = setRandomizedInterval(function () {
editor.replaceSelection(input.charAt(i));
i = (i + 1) % l;
}, 200, 50);
return {
cancel: cancel
};
};
return {
testInput: testInput,
testPad: testPad,
testCode: testCode,
setRandomizedInterval: setRandomizedInterval
};
});

View File

@ -6,11 +6,20 @@
define(function() {
var config = {};
/* Select the buttons displayed on the main page to create new collaborative sessions
* Existing types : pad, code, poll, slide
/* Select the buttons displayed on the main page to create new collaborative sessions.
* Removing apps from the list will prevent users from accessing them. They will instead be
* redirected to the drive.
* You should never remove the drive from this list.
*/
config.availablePadTypes = ['drive', 'pad', 'code', 'slide', 'poll', 'kanban', 'whiteboard',
'oodoc', 'ooslide', 'oocell', 'file', 'todo', 'contacts'];
/* The registered only types are apps restricted to registered users.
* You should never remove apps from this list unless you know what you're doing. The apps
* listed here by default can't work without a user account.
* You can however add apps to this list. The new apps won't be visible for unregistered
* users and these users will be redirected to the login page if they still try to access
* the app
*/
config.registeredOnlyTypes = ['file', 'contacts', 'oodoc', 'ooslide', 'oocell'];
/* Cryptpad apps use a common API to display notifications to users
@ -74,18 +83,19 @@ define(function() {
// Customize the icon used for each application.
// You can update the colors by making a copy of /customize.dist/src/less2/include/colortheme.less
config.applicationsIcon = {
file: 'fa-file-text-o',
pad: 'fa-file-word-o',
code: 'fa-file-code-o',
slide: 'fa-file-powerpoint-o',
poll: 'fa-calendar',
whiteboard: 'fa-paint-brush',
todo: 'fa-tasks',
contacts: 'fa-users',
file: 'cptools-file',
fileupload: 'cptools-file-upload',
pad: 'cptools-pad',
code: 'cptools-code',
slide: 'cptools-slide',
poll: 'cptools-poll',
whiteboard: 'cptools-whiteboard',
todo: 'cptools-todo',
contacts: 'cptools-contacts',
kanban: 'cptools-kanban',
oodoc: 'fa-file-word-o',
ooslide: 'fa-file-powerpoint-o',
oocell: 'fa-file-excel-o',
kanban: 'fa-columns',
drive: 'fa-hdd-o',
};
@ -128,13 +138,13 @@ define(function() {
// SharedWorkers allow us to load only one websocket and one user drive for all the browser tabs,
// making it much faster to open new tabs.
// Warning: This is an experimental feature. It will be enabled by default once we're sure it's stable.
config.disableWorkers = true;
config.disableWorkers = false;
// Shared folder are in a beta-test state. They are likely to disappear from a user's drive
// spontaneously, resulting in the deletion of the entire folder's content.
// We highly recommend to keep them disabled until they are stable enough to be enabled
// by default by the CryptPad developers.
config.disableSharedFolders = true;
config.disableSharedFolders = false;
return config;
});

View File

@ -13,6 +13,10 @@ define(function () {
storageKey: 'filesData',
tokenKey: 'loginToken',
displayPadCreationScreen: 'displayPadCreationScreen',
deprecatedKey: 'deprecated'
deprecatedKey: 'deprecated',
// Sub
plan: 'CryptPad_plan',
// Apps
criticalApps: ['profile', 'settings', 'debug']
};
});

View File

@ -12,6 +12,7 @@ define([
var hexToBase64 = Util.hexToBase64;
var base64ToHex = Util.base64ToHex;
Hash.encodeBase64 = Nacl.util.encodeBase64;
Hash.decodeBase64 = Nacl.util.decodeBase64;
// This implementation must match that on the server
// it's used for a checksum

View File

@ -16,7 +16,6 @@ define([
'/customize/application_config.js',
'/bower_components/alertifyjs/dist/js/alertify.js',
'/common/tippy/tippy.min.js',
'/customize/pages.js',
'/common/hyperscript.js',
'/customize/loading.js',
'/common/test.js',
@ -26,7 +25,7 @@ define([
'css!/common/tippy/tippy.css',
'css!/common/jquery-ui/jquery-ui.min.css'
], function ($, Messages, Util, Hash, Notifier, AppConfig,
Alertify, Tippy, Pages, h, Loading, Test) {
Alertify, Tippy, h, Loading, Test) {
var UI = {};
/*
@ -37,6 +36,11 @@ define([
// set notification timeout
Alertify._$$alertify.delay = AppConfig.notificationTimeout || 5000;
var setHTML = UI.setHTML = function (e, html) {
e.innerHTML = html;
return e;
};
var findCancelButton = UI.findCancelButton = function (root) {
if (root) {
return $(root).find('button.cancel').last();
@ -761,8 +765,11 @@ define([
var $icon = $defaultIcon.clone();
if (AppConfig.applicationsIcon && AppConfig.applicationsIcon[type]) {
var icon = AppConfig.applicationsIcon[type];
var font = icon.indexOf('cptools') === 0 ? 'cptools' : 'fa';
if (type === 'fileupload') { type = 'file'; }
var appClass = ' cp-icon cp-icon-color-'+type;
$icon = $('<span>', {'class': 'fa ' + AppConfig.applicationsIcon[type] + appClass});
$icon = $('<span>', {'class': font + ' ' + icon + appClass});
}
return $icon;
@ -875,9 +882,92 @@ define([
});
};
UI.createCheckbox = Pages.createCheckbox;
UI.createCheckbox = function (id, labelTxt, checked, opts) {
opts = opts|| {};
// Input properties
var inputOpts = {
type: 'checkbox',
id: id
};
if (checked) { inputOpts.checked = 'checked'; }
$.extend(inputOpts, opts.input || {});
UI.createRadio = Pages.createRadio;
// Label properties
var labelOpts = {};
$.extend(labelOpts, opts.label || {});
if (labelOpts.class) { labelOpts.class += ' cp-checkmark'; }
// Mark properties
var markOpts = { tabindex: 0 };
$.extend(markOpts, opts.mark || {});
var input = h('input', inputOpts);
var mark = h('span.cp-checkmark-mark', markOpts);
var label = h('span.cp-checkmark-label', labelTxt);
$(mark).keydown(function (e) {
if (e.which === 32) {
e.stopPropagation();
e.preventDefault();
$(input).prop('checked', !$(input).is(':checked'));
$(input).change();
}
});
$(input).change(function () { $(mark).focus(); });
return h('label.cp-checkmark', labelOpts, [
input,
mark,
label
]);
};
UI.createRadio = function (name, id, labelTxt, checked, opts) {
opts = opts|| {};
// Input properties
var inputOpts = {
type: 'radio',
id: id,
name: name
};
if (checked) { inputOpts.checked = 'checked'; }
$.extend(inputOpts, opts.input || {});
// Label properties
var labelOpts = {};
$.extend(labelOpts, opts.label || {});
if (labelOpts.class) { labelOpts.class += ' cp-checkmark'; }
// Mark properties
var markOpts = { tabindex: 0 };
$.extend(markOpts, opts.mark || {});
var input = h('input', inputOpts);
var mark = h('span.cp-radio-mark', markOpts);
var label = h('span.cp-checkmark-label', labelTxt);
$(mark).keydown(function (e) {
if (e.which === 32) {
e.stopPropagation();
e.preventDefault();
$(input).prop('checked', !$(input).is(':checked'));
$(input).change();
}
});
$(input).change(function () { $(mark).focus(); });
var radio = h('label', labelOpts, [
input,
mark,
label
]);
$(radio).addClass('cp-radio');
return radio;
};
UI.cornerPopup = function (text, actions, footer, opts) {
opts = opts || {};
@ -887,14 +977,14 @@ define([
var popup = h('div.cp-corner-container', [
minimize,
maximize,
h('div.cp-corner-filler', { style: "width:130px;" }),
h('div.cp-corner-filler', { style: "width:90px;" }),
h('div.cp-corner-filler', { style: "width:110px;" }),
h('div.cp-corner-filler', { style: "width:80px;" }),
h('div.cp-corner-filler', { style: "width:60px;" }),
h('div.cp-corner-filler', { style: "width:40px;" }),
h('div.cp-corner-filler', { style: "width:20px;" }),
h('div.cp-corner-text', text),
setHTML(h('div.cp-corner-text'), text),
h('div.cp-corner-actions', actions),
Pages.setHTML(h('div.cp-corner-footer'), footer)
setHTML(h('div.cp-corner-footer'), footer)
]);
$(minimize).click(function () {

View File

@ -150,7 +150,8 @@ define([
}
cfg.friendComplete({
logText: Messages.contacts_added,
netfluxId: sender
netfluxId: sender,
friend: msgData
});
var msg = ["FRIEND_REQ_ACK", chan];
var msgStr = Crypto.encrypt(JSON.stringify(msg), key);
@ -163,7 +164,7 @@ define([
if (i !== -1) { pendingRequests.splice(i, 1); }
cfg.friendComplete({
logText: Messages.contacts_rejected,
netfluxId: sender
netfluxId: sender,
});
cfg.updateMetadata();
return;
@ -180,7 +181,8 @@ define([
}
cfg.friendComplete({
logText: Messages.contacts_added,
netfluxId: sender
netfluxId: sender,
friend: data
});
});
return;

File diff suppressed because it is too large Load Diff

View File

@ -12,13 +12,25 @@ define([
}
};
Notifier.notify = function () {
Notifier.notify = function (data) {
if (Visible.isSupported() && !Visible.currently()) {
if (data) {
var title = data.title;
if (document.title) { title += ' (' + document.title + ')'; }
Notify.system(data.msg, title);
return;
}
Notifier.unnotify();
notify.tabNotification = Notify.tab(1000, 10);
}
};
Notifier.getPermission = function () {
if (Notify.isSupported()) {
Notify.getPermission();
}
};
if (Visible.isSupported()) {
Visible.onChange(function (yes) {
if (yes) { Notifier.unnotify(); }

View File

@ -12,10 +12,11 @@ define([
'/common/clipboard.js',
'/customize/messages.js',
'/customize/application_config.js',
'/customize/pages.js',
'/bower_components/nthen/index.js',
'css!/customize/fonts/cptools/style.css'
], function ($, Config, Util, Hash, Language, UI, Constants, Feedback, h, MediaTag, Clipboard,
Messages, AppConfig, NThen) {
Messages, AppConfig, Pages, NThen) {
var UIElements = {};
// Configure MediaTags to use our local viewer
@ -155,7 +156,7 @@ define([
}
var parsed = Hash.parsePadUrl(data.href || data.roHref);
if (owned && parsed.hashData.type === 'pad') {
if (!data.noEditPassword && owned && parsed.hashData.type === 'pad') {
var sframeChan = common.getSframeChannel();
var changePwTitle = Messages.properties_changePassword;
var changePwConfirm = Messages.properties_confirmChange;
@ -630,23 +631,25 @@ define([
if (!data.FM) { return; }
var $input = $('<input>', {
'type': 'file',
'style': 'display: none;'
'style': 'display: none;',
'multiple': 'multiple'
}).on('change', function (e) {
var file = e.target.files[0];
var ev = {
target: data.target
};
if (data.filter && !data.filter(file)) {
return;
}
if (data.transformer) {
data.transformer(file, function (newFile) {
data.FM.handleFile(newFile, ev);
if (callback) { callback(); }
});
return;
}
data.FM.handleFile(file, ev);
var files = Util.slice(e.target.files);
files.forEach(function (file) {
var ev = {
target: data.target
};
if (data.filter && !data.filter(file)) {
return;
}
if (data.transformer) {
data.transformer(file, function (newFile) {
data.FM.handleFile(newFile, ev);
});
return;
}
data.FM.handleFile(file, ev);
});
if (callback) { callback(); }
});
if (data.accept) { $input.attr('accept', data.accept); }
@ -765,7 +768,7 @@ define([
break;
case 'print':
button = $('<button>', {
title: Messages.printButtonTitle,
title: Messages.printButtonTitle2,
'class': "fa fa-print cp-toolbar-icon-print",
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.printText));
break;
@ -1132,14 +1135,30 @@ define([
common.setAttribute(['hideHelp', type], true);
};
$(closeButton).click(function () { toggleHelp(true); });
var showMore = function () {
$(text).addClass("cp-help-small");
var $dot = $('<span>').text('...').appendTo($(text).find('h1'));
$(text).click(function () {
$(text).removeClass('cp-help-small');
$(text).off('click');
$dot.remove();
});
};
$(closeButton).click(function (e) {
e.stopPropagation();
toggleHelp(true);
});
$toolbarButton.click(function () {
toggleHelp();
});
common.getAttribute(['hideHelp', type], function (err, val) {
if ($(window).height() < 800 && $(window).width() < 800) { return void toggleHelp(true); }
if (val === true) { toggleHelp(true); }
//if ($(window).height() < 800 || $(window).width() < 800) { return void toggleHelp(true); }
if (val === true) { return void toggleHelp(true); }
if (!val && ($(window).height() < 800 || $(window).width() < 800)) {
return void showMore();
}
});
return {
@ -1205,6 +1224,13 @@ define([
var emojis = emojiStringToArray(str);
return isEmoji(emojis[0])? emojis[0]: str[0];
};
var avatars = {};
UIElements.setAvatar = function (hash, data) {
avatars[hash] = data;
};
UIElements.getAvatar = function (hash) {
return avatars[hash];
};
UIElements.displayAvatar = function (Common, $container, href, name, cb) {
var displayDefault = function () {
var text = getFirstEmojiOrCharacter(name);
@ -1434,6 +1460,9 @@ define([
};
var show = function () {
var wh = $(window).height();
var topPos = $container[0].getBoundingClientRect().bottom;
$innerblock.css('max-height', Math.floor(wh - topPos - 1)+'px');
$innerblock.show();
$innerblock.find('.cp-dropdown-element-active').removeClass('cp-dropdown-element-active');
if (config.isSelect && value) {
@ -1523,8 +1552,9 @@ define([
var displayNameCls = config.displayNameCls || 'cp-toolbar-user-name';
var $displayedName = $('<span>', {'class': displayNameCls});
var accountName = metadataMgr.getPrivateData().accountName;
var origin = metadataMgr.getPrivateData().origin;
var priv = metadataMgr.getPrivateData();
var accountName = priv.accountName;
var origin = priv.origin;
var padType = metadataMgr.getMetadata().type;
var $userName = $('<span>');
@ -1548,7 +1578,7 @@ define([
content: $userAdminContent.html()
});
}
if (padType !== 'drive') {
if (padType !== 'drive' || (!accountName && priv.newSharedFolder)) {
options.push({
tag: 'a',
attributes: {
@ -1792,13 +1822,16 @@ define([
var $container = $('<div>');
var i = 0;
AppConfig.availablePadTypes.forEach(function (p) {
var types = AppConfig.availablePadTypes.filter(function (p) {
if (p === 'drive') { return; }
if (p === 'contacts') { return; }
if (p === 'todo') { return; }
if (p === 'file') { return; }
if (!common.isLoggedIn() && AppConfig.registeredOnlyTypes &&
AppConfig.registeredOnlyTypes.indexOf(p) !== -1) { return; }
return true;
});
types.forEach(function (p) {
var $element = $('<li>', {
'class': 'cp-icons-element',
'id': 'cp-newpad-icons-'+ (i++)
@ -1822,7 +1855,7 @@ define([
var selected = -1;
var next = function () {
selected = ++selected % 5;
selected = ++selected % types.length;
$container.find('.cp-icons-element-selected').removeClass('cp-icons-element-selected');
$container.find('#cp-newpad-icons-'+selected).addClass('cp-icons-element-selected');
};
@ -1896,7 +1929,13 @@ define([
onSelect: function (data) {
if (data.type === type && first) {
UI.addLoadingScreen({hideTips: true});
sframeChan.query('Q_TEMPLATE_USE', data.href, function () {
var chatChan = common.getPadChat();
var cursorChan = common.getCursorChannel();
sframeChan.query('Q_TEMPLATE_USE', {
href: data.href,
chat: chatChan,
cursor: cursorChan
}, function () {
first = false;
UI.removeLoadingScreen();
Feedback.send('TEMPLATE_USED');
@ -2338,12 +2377,63 @@ define([
$(password).find('.cp-password-input').focus();
};
var crowdfundingState = false;
UIElements.displayCrowdfunding = function (common) {
if (crowdfundingState) { return; }
if (AppConfig.disableCrowdfundingMessages) { return; }
var priv = common.getMetadataMgr().getPrivateData();
if (priv.plan) { return; }
crowdfundingState = true;
setTimeout(function () {
common.getAttribute(['general', 'crowdfunding'], function (err, val) {
if (err || val === false) { return; }
// Display the popup
var text = Messages.crowdfunding_popup_text;
var yes = h('button.cp-corner-primary', Messages.crowdfunding_popup_yes);
var no = h('button.cp-corner-primary', Messages.crowdfunding_popup_no);
var never = h('button.cp-corner-cancel', Messages.crowdfunding_popup_never);
var actions = h('div', [yes, no, never]);
var modal = UI.cornerPopup(text, actions, null, {big: true});
$(yes).click(function () {
modal.delete();
common.openURL('https://opencollective.com/cryptpad/contribute');
Feedback.send('CROWDFUNDING_YES');
});
$(modal.popup).find('a').click(function (e) {
e.stopPropagation();
e.preventDefault();
modal.delete();
common.openURL('https://opencollective.com/cryptpad/');
Feedback.send('CROWDFUNDING_LINK');
});
$(no).click(function () {
modal.delete();
Feedback.send('CROWDFUNDING_NO');
});
$(never).click(function () {
modal.delete();
common.setAttribute(['general', 'crowdfunding'], false);
Feedback.send('CROWDFUNDING_NEVER');
});
});
}, 5000);
};
var storePopupState = false;
UIElements.displayStorePadPopup = function (common, data) {
if (storePopupState) { return; }
storePopupState = true;
if (data && data.stored) { return; } // We won't display the popup for dropped files
var priv = common.getMetadataMgr().getPrivateData();
var text = Messages.autostore_notstored;
var typeMsg = priv.pathname.indexOf('/file/') !== -1 ? Messages.autostore_file :
priv.pathname.indexOf('/drive/') !== -1 ? Messages.autostore_sf :
Messages.autostore_pad;
var text = Messages._getKey('autostore_notstored', [typeMsg]);
var footer = Messages.autostore_settings;
var hide = h('button.cp-corner-cancel', Messages.autostore_hide);
@ -2359,15 +2449,20 @@ define([
});
$(hide).click(function () {
UIElements.displayCrowdfunding(common);
modal.delete();
});
$(store).click(function () {
modal.delete();
common.getSframeChannel().query("Q_AUTOSTORE_STORE", null, function (err, obj) {
if (err || (obj && obj.error)) {
console.error(err || obj.error);
var error = err || (obj && obj.error);
if (error) {
if (error === 'E_OVER_LIMIT') {
return void UI.warn(Messages.pinLimitReached);
}
return void UI.warn(Messages.autostore_error);
}
modal.delete();
UIElements.displayCrowdfunding(common);
UI.log(Messages.autostore_saved);
});
});

View File

@ -138,11 +138,19 @@ define([], function () {
};
// given a path, asynchronously return an arraybuffer
Util.fetch = function (src, cb) {
Util.fetch = function (src, cb, progress) {
var CB = Util.once(cb);
var xhr = new XMLHttpRequest();
xhr.open("GET", src, true);
if (progress) {
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
progress(percentComplete);
}
}, false);
}
xhr.responseType = "arraybuffer";
xhr.onerror = function (err) { CB(err); };
xhr.onload = function () {
@ -262,7 +270,7 @@ define([], function () {
}
for (var k in b) {
if (Util.isObject(b[k])) {
a[k] = {};
a[k] = Util.isObject(a[k]) ? a[k] : {};
Util.extend(a[k], b[k]);
continue;
}
@ -289,6 +297,15 @@ define([], function () {
return false;
};
Util.hexToRGB = function (hex) {
var h = hex.replace(/^#/, '');
return [
parseInt(h.slice(0,2), 16),
parseInt(h.slice(2,4), 16),
parseInt(h.slice(4,6), 16),
];
};
return Util;
});
}(self));

View File

@ -12,11 +12,18 @@ define([
S.cb(err, doc);
S.done = true;
var disconnect = Util.find(S, ['network', 'disconnect']);
if (typeof(disconnect) === 'function') { disconnect(); }
var abort = Util.find(S, ['realtime', 'realtime', 'abort']);
if (!S.hasNetwork) {
var disconnect = Util.find(S, ['network', 'disconnect']);
if (typeof(disconnect) === 'function') { disconnect(); }
}
if (S.leave) {
try {
S.leave();
} catch (e) { console.log(e); }
}
var abort = Util.find(S, ['session', 'realtime', 'abort']);
if (typeof(abort) === 'function') {
S.realtime.realtime.sync();
S.session.realtime.sync();
abort();
}
};
@ -51,13 +58,19 @@ define([
opt = opt || {};
var config = makeConfig(hash, opt.password);
var Session = { cb: cb, };
var Session = { cb: cb, hasNetwork: Boolean(opt.network) };
config.onReady = function (info) {
var rt = Session.session = info.realtime;
Session.network = info.network;
Session.leave = info.leave;
finish(Session, void 0, rt.getUserDoc());
};
config.onChannelError = function (info) {
finish(Session, info.error);
};
overwrite(config, opt);
Session.realtime = CPNetflux.start(config);

View File

@ -38,6 +38,7 @@ define([
}
};
// Upgrade and donate URLs duplicated in pages.js
var origin = encodeURIComponent(window.location.hostname);
var common = window.Cryptpad = {
Messages: Messages,
@ -58,6 +59,19 @@ define([
cb();
};
common.makeNetwork = function (cb) {
require([
'/bower_components/netflux-websocket/netflux-client.js',
'/common/outer/network-config.js'
], function (Netflux, NetConfig) {
var wsUrl = NetConfig.getWebsocketURL();
Netflux.connect(wsUrl).then(function (network) {
cb(null, network);
}, function (err) {
cb(err);
});
});
};
// RESTRICTED
// Settings only
@ -89,6 +103,12 @@ define([
cb(obj);
});
};
common.loadSharedFolder = function (id, data, cb) {
postMessage("LOAD_SHARED_FOLDER", {
id: id,
data: data
}, cb);
};
// Settings and ready
common.mergeAnonDrive = function (cb) {
var data = {
@ -121,6 +141,7 @@ define([
href: '/drive/#' + Hash.getEditHashFromKeys(secret),
roHref: '/drive/#' + Hash.getViewHashFromKeys(secret),
channel: secret.channel,
password: secret.password,
ctime: +new Date()
}
}, cb);
@ -345,6 +366,9 @@ define([
};
common.getPadAttribute = function (attr, cb, href) {
href = Hash.getRelativeHref(href || window.location.href);
if (!href) {
return void cb('E404');
}
postMessage("GET_PAD_ATTRIBUTE", {
href: href,
attr: attr,
@ -469,9 +493,10 @@ define([
});
};
common.useTemplate = function (href, Crypt, cb, optsPut) {
common.useTemplate = function (data, Crypt, cb, optsPut) {
// opts is used to overrides options for chainpad-netflux in cryptput
// it allows us to add owners and expiration time if it is a new file
var href = data.href;
var parsed = Hash.parsePadUrl(href);
var parsed2 = Hash.parsePadUrl(window.location.href);
@ -507,8 +532,13 @@ define([
}
if (typeof(meta) === "object") {
meta.defaultTitle = meta.title || meta.defaultTitle;
delete meta.users;
meta.title = "";
delete meta.users;
delete meta.chat2;
delete meta.chat;
delete meta.cursor;
if (data.chat) { meta.chat2 = data.chat; }
if (data.cursor) { meta.cursor = data.cursor; }
}
val = JSON.stringify(parsed);
} catch (e) {
@ -595,39 +625,18 @@ define([
// Messenger
var messenger = common.messenger = {};
messenger.getFriendList = function (cb) {
postMessage("CONTACTS_GET_FRIEND_LIST", null, cb);
messenger.execCommand = function (data, cb) {
postMessage("CHAT_COMMAND", data, cb);
};
messenger.getMyInfo = function (cb) {
postMessage("CONTACTS_GET_MY_INFO", null, cb);
messenger.onEvent = Util.mkEvent();
// Cursor
var cursor = common.cursor = {};
cursor.execCommand = function (data, cb) {
postMessage("CURSOR_COMMAND", data, cb);
};
messenger.getFriendInfo = function (curvePublic, cb) {
postMessage("CONTACTS_GET_FRIEND_INFO", curvePublic, cb);
};
messenger.removeFriend = function (curvePublic, cb) {
postMessage("CONTACTS_REMOVE_FRIEND", curvePublic, cb);
};
messenger.openFriendChannel = function (curvePublic, cb) {
postMessage("CONTACTS_OPEN_FRIEND_CHANNEL", curvePublic, cb);
};
messenger.getFriendStatus = function (curvePublic, cb) {
postMessage("CONTACTS_GET_FRIEND_STATUS", curvePublic, cb);
};
messenger.getMoreHistory = function (data, cb) {
postMessage("CONTACTS_GET_MORE_HISTORY", data, cb);
};
messenger.sendMessage = function (data, cb) {
postMessage("CONTACTS_SEND_MESSAGE", data, cb);
};
messenger.setChannelHead = function (data, cb) {
postMessage("CONTACTS_SET_CHANNEL_HEAD", data, cb);
};
messenger.onMessageEvent = Util.mkEvent();
messenger.onJoinEvent = Util.mkEvent();
messenger.onLeaveEvent = Util.mkEvent();
messenger.onUpdateEvent = Util.mkEvent();
messenger.onFriendEvent = Util.mkEvent();
messenger.onUnfriendEvent = Util.mkEvent();
cursor.onEvent = Util.mkEvent();
// Pad RPC
var pad = common.padRpc = {};
@ -1052,13 +1061,10 @@ define([
common.onNetworkReconnect.fire(data);
});
},
// Messenger
CONTACTS_MESSAGE: common.messenger.onMessageEvent.fire,
CONTACTS_JOIN: common.messenger.onJoinEvent.fire,
CONTACTS_LEAVE: common.messenger.onLeaveEvent.fire,
CONTACTS_UPDATE: common.messenger.onUpdateEvent.fire,
CONTACTS_FRIEND: common.messenger.onFriendEvent.fire,
CONTACTS_UNFRIEND: common.messenger.onUnfriendEvent.fire,
// Chat
CHAT_EVENT: common.messenger.onEvent.fire,
// Cursor
CURSOR_EVENT: common.cursor.onEvent.fire,
// Pad
PAD_READY: common.padRpc.onReadyEvent.fire,
PAD_MESSAGE: common.padRpc.onMessageEvent.fire,
@ -1356,6 +1362,11 @@ define([
console.log('Posting CONNECT');
postMessage('CONNECT', cfg, function (data) {
// FIXME data should always exist
// this indicates a false condition in sharedWorker
// got here via a reference error:
// uncaught exception: TypeError: data is undefined
if (!data) { throw new Error('FALSE_INIT'); }
if (data.error) { throw new Error(data.error); }
if (data.state === 'ALREADY_INIT') {
data = data.returned;
@ -1425,7 +1436,7 @@ define([
postMessage("INIT_RPC", null, waitFor(function (obj) {
console.log('RPC handshake complete');
if (obj.error) { return; }
localStorage.plan = obj.plan;
localStorage[Constants.plan] = obj.plan;
}));
} else if (PINNING_ENABLED) {
console.log('not logged in. pads will not be pinned');

View File

@ -1,5 +1,5 @@
define([
'/common/treesome.js',
'/common/cursor-treesome.js',
'/bower_components/rangy/rangy-core.min.js'
], function (Tree, Rangy) {
var verbose = function (x) { if (window.verboseMode) { console.log(x); } };
@ -8,6 +8,253 @@ define([
var Cursor = function (inner) {
var cursor = {};
var getTextNodeValue = function (el) {
if (!el.data) { return; }
// We want to transform html entities into their code (non-breaking spaces into $&nbsp;)
var div = document.createElement('div');
div.innerText = el.data;
return div.innerHTML;
};
// Store the cursor position as an offset from the beginning of the text HTML content
var offsetRange = cursor.offsetRange = {
start: 0,
end: 0
};
// Get the length of the opening tag of an node (<body class="cp"> ==> 17)
var getOpeningTagLength = function (node) {
if (node.nodeType === node.TEXT_NODE) { return 0; }
var html = node.outerHTML;
var tagRegex = /^(<\s*[a-zA-Z-]*[^>]*>)(.+)/;
var match = tagRegex.exec(html);
var res = match && match.length > 1 ? match[1].length : 0;
return res;
};
// Get the offset recursively. We start with <body> and continue following the
// path to the range
var offsetInNode = function (element, offset, path, range) {
if (path.length === 0) {
offset += getOpeningTagLength(range.el);
if (range.el.nodeType === range.el.TEXT_NODE) {
var div = document.createElement('div');
div.innerText = range.el.data.slice(0, range.offset);
return offset + div.innerHTML.length;
}
return offset + range.offset;
}
offset += getOpeningTagLength(element);
for (var i = 0; i < element.childNodes.length; i++) {
if (element.childNodes[i] === path[0]) {
return offsetInNode(path.shift(), offset, path, range);
}
// It is not yet our path, add the length of the text node or tag's outerHTML
offset += (getTextNodeValue(element.childNodes[i]) || element.childNodes[i].outerHTML).length;
}
};
// Get the cursor position as a range and transform it into
// an offset from the beginning of the outer HTML
var getOffsetFromRange = function (element) {
var doc = element.ownerDocument || element.document;
var win = doc.defaultView || doc.parentWindow;
var o = {
start: 0,
end: 0
};
if (typeof win.getSelection !== "undefined") {
var sel = win.getSelection();
if (sel.rangeCount > 0) {
var range = win.getSelection().getRangeAt(0);
// Do it for both start and end
['start', 'end'].forEach(function (t) {
var inNode = {
el: range[t + 'Container'],
offset: range[t + 'Offset']
};
while (inNode.el.nodeType !== Node.TEXT_NODE && inNode.el.childNodes.length > inNode.offset) {
inNode.el = inNode.el.childNodes[inNode.offset];
inNode.offset = 0;
}
var current = inNode.el;
var path = [];
while (current !== element) {
path.unshift(current);
current = current.parentElement;
}
if (current === element) { // Should always be the case
o[t] = offsetInNode(current, 0, path, inNode);
} else {
console.error('???');
}
});
}
}
return o;
};
// Update the value of the offset
// This should be called before applying changes to the document
cursor.offsetUpdate = function () {
try {
var range = getOffsetFromRange(inner);
offsetRange.start = range.start;
offsetRange.end = range.end;
} catch (e) {
console.error(e);
}
};
// Transform the offset value using the operations from the diff
// between the old and the new states of the document.
var offsetTransformRange = function (offset, ops) {
var transformCursor = function (cursor, op) {
if (!op) { return cursor; }
var pos = op.offset;
var remove = op.toRemove;
var insert = op.toInsert.length;
if (typeof cursor === 'undefined') { return; }
if (typeof remove === 'number' && pos < cursor) {
cursor -= Math.min(remove, cursor - pos);
}
if (typeof insert === 'number' && pos < cursor) {
cursor += insert;
}
return cursor;
};
var c = offset;
if (Array.isArray(ops)) {
for (var i = ops.length - 1; i >= 0; i--) {
c = transformCursor(c, ops[i]);
}
offset = c;
}
return offset;
};
// Get the range starting from <body> and the offset value.
// We substract length of HTML content to the offset until we reach a text node or 0.
// If we reach a text node, it means we're in the final possible child and the
// current valu of the offset is the range one.
// If we reach 0 or a negative value, it means the range in is the current tag
// and we should use offset 0.
var getFinalRange = function (el, offset) {
if (el.nodeType === el.TEXT_NODE) {
// This should be the final text node
var txt = document.createElement("textarea");
txt.appendChild(el.cloneNode());
txt.innerHTML = txt.innerHTML.slice(0, offset);
return {
el: el,
offset: txt.value.length
};
}
if (el.tagName === 'BR') {
// If the range is in a <br>, we have a brFix that will make it better later
return {
el: el,
offset: 0
};
}
// Remove the current tag opening length
offset = offset - getOpeningTagLength(el);
if (offset <= 0) {
// Return the current node...
return {
el: el,
offset: 0
};
}
// For each child, if they length is greater than the current offset, they are
// containing the range element we're looking for.
// Otherwise, our range element is in a later sibling and we can just substract
// their length.
var newOffset = offset;
for (var i = 0; i < el.childNodes.length; i++) {
try {
newOffset -= (getTextNodeValue(el.childNodes[i]) || el.childNodes[i].outerHTML).length;
} catch (e) {
console.log(el);
console.log(el.childNodes[i]);
}
if (newOffset <= 0) {
return getFinalRange(el.childNodes[i], offset);
}
offset = newOffset;
}
// New offset ends up in the closing tag
// ==> return the last child...
if (el.childNodes.length) {
return getFinalRange(el.childNodes[el.childNodes.length - 1], offset);
} else {
return {
el: el,
offset: 0
};
}
};
// Transform an offset into a range that we can use to restore the cursor
var getRangeFromOffset = function (element) {
var range = {
start: {
el: null,
offset: 0
},
end: {
el: null,
offset: 0
}
};
['start', 'end'].forEach(function (t) {
var offset = offsetRange[t];
var res = getFinalRange(element, offset);
range[t].el = res.el;
range[t].offset = res.offset;
});
return range;
};
cursor.getNewOffset = function (ops) {
return {
selectionStart: offsetTransformRange(offsetRange.start, ops),
selectionEnd: offsetTransformRange(offsetRange.end, ops)
};
};
cursor.getNewRange = function (data, ops) {
offsetRange.start = offsetTransformRange(data.start, ops);
offsetRange.end = offsetTransformRange(data.end, ops);
var range = getRangeFromOffset(inner);
return range;
};
// Restore the cursor position after applying the changes.
cursor.restoreOffset = function (ops) {
try {
offsetRange.start = offsetTransformRange(offsetRange.start, ops);
offsetRange.end = offsetTransformRange(offsetRange.end, ops);
var range = getRangeFromOffset(inner);
var sel = cursor.makeSelection();
var r = cursor.makeRange();
cursor.fixStart(range.start.el, range.start.offset);
cursor.fixEnd(range.end.el, range.end.offset);
cursor.fixSelection(sel, r);
cursor.brFix();
} catch (e) {
console.error(e);
}
};
// there ought to only be one cursor at a time, so let's just
// keep it internally
var Range = cursor.Range = {
@ -124,6 +371,7 @@ define([
cursor.pushDelta = function (oldVal, newVal) {
if (oldVal === newVal) { return; }
var commonStart = 0;
while (oldVal.charAt(commonStart) === newVal.charAt(commonStart)) {
commonStart++;
@ -156,6 +404,31 @@ define([
};
};
cursor.transformRange = function (cursorRange, ops) {
var transformCursor = function (cursor, op) {
if (!op) { return cursor; }
var pos = op.offset;
var remove = op.toRemove;
var insert = op.toInsert.length;
if (typeof cursor === 'undefined') { return; }
if (typeof remove === 'number' && pos < cursor) {
cursor -= Math.min(remove, cursor - pos);
}
if (typeof insert === 'number' && pos < cursor) {
cursor += insert;
}
return cursor;
};
var c = cursorRange.offset;
if (Array.isArray(ops)) {
for (var i = ops.length - 1; i >= 0; i--) {
c = transformCursor(c, ops[i]);
}
cursorRange.offset = c;
}
};
cursor.brFix = function () {
cursor.update();
var start = Range.start;

View File

@ -4,20 +4,41 @@ define([
'/common/common-hash.js',
'/common/common-util.js',
'/common/media-tag.js',
'/common/highlight/highlight.pack.js',
'/bower_components/diff-dom/diffDOM.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
],function ($, Marked, Hash, Util, MediaTag) {
'css!/common/highlight/styles/github.css'
],function ($, Marked, Hash, Util, MediaTag, Highlight) {
var DiffMd = {};
var DiffDOM = window.diffDOM;
var renderer = new Marked.Renderer();
var highlighter = function () {
return function(code, lang) {
if (lang) {
try {
return Highlight.highlight(lang, code).value;
} catch (e) {
return code;
}
}
return code;
};
};
Marked.setOptions({
renderer: renderer
//sanitize: true, // Disable HTML
renderer: renderer,
highlight: highlighter(),
});
DiffMd.render = function (md) {
return Marked(md);
DiffMd.render = function (md, sanitize) {
return Marked(md, {
sanitize: sanitize
});
};
var mediaMap = {};
@ -25,9 +46,11 @@ define([
// Tasks list
var checkedTaskItemPtn = /^\s*(<p>)?\[[xX]\](<\/p>)?\s*/;
var uncheckedTaskItemPtn = /^\s*(<p>)?\[ ?\](<\/p>)?\s*/;
var bogusCheckPtn = /<input( checked=""){0,1} disabled="" type="checkbox">/;
renderer.listitem = function (text) {
var isCheckedTaskItem = checkedTaskItemPtn.test(text);
var isUncheckedTaskItem = uncheckedTaskItemPtn.test(text);
var hasBogusInput = bogusCheckPtn.test(text);
if (isCheckedTaskItem) {
text = text.replace(checkedTaskItemPtn,
'<i class="fa fa-check-square" aria-hidden="true"></i>&nbsp;') + '\n';
@ -36,6 +59,15 @@ define([
text = text.replace(uncheckedTaskItemPtn,
'<i class="fa fa-square-o" aria-hidden="true"></i>&nbsp;') + '\n';
}
if (!isCheckedTaskItem && !isUncheckedTaskItem && hasBogusInput) {
if (/checked/.test(text)) {
text = text.replace(bogusCheckPtn,
'<i class="fa fa-check-square" aria-hidden="true"></i>&nbsp;') + '\n';
} else if (/disabled/.test(text)) {
text = text.replace(bogusCheckPtn,
'<i class="fa fa-square-o" aria-hidden="true"></i>&nbsp;') + '\n';
}
}
var cls = (isCheckedTaskItem || isUncheckedTaskItem) ? ' class="todo-list-item"' : '';
return '<li'+ cls + '>' + text + '</li>\n';
};
@ -74,8 +106,9 @@ define([
'IFRAME',
'OBJECT',
'APPLET',
//'VIDEO', // privacy implications of videos are the same as images
//'AUDIO', // same with audio
'VIDEO', // privacy implications of videos are the same as images
'AUDIO', // same with audio
'SVG'
];
var unsafeTag = function (info) {
/*if (info.node && $(info.node).parents('media-tag').length) {
@ -90,10 +123,10 @@ define([
}
if (['addElement', 'replaceElement'].indexOf(info.diff.action) !== -1) {
var msg = "Rejecting forbidden tag of type (%s)";
if (info.diff.element && forbiddenTags.indexOf(info.diff.element.nodeName) !== -1) {
if (info.diff.element && forbiddenTags.indexOf(info.diff.element.nodeName.toUpperCase()) !== -1) {
console.log(msg, info.diff.element.nodeName);
return true;
} else if (info.diff.newValue && forbiddenTags.indexOf(info.diff.newValue.nodeName) !== -1) {
} else if (info.diff.newValue && forbiddenTags.indexOf(info.diff.newValue.nodeName.toUpperCase()) !== -1) {
console.log("Replacing restricted element type (%s) with PRE", info.diff.newValue.nodeName);
info.diff.newValue.nodeName = 'PRE';
}
@ -115,7 +148,7 @@ define([
var removeForbiddenTags = function (root) {
if (!root) { return; }
if (forbiddenTags.indexOf(root.nodeName) !== -1) { removeNode(root); }
if (forbiddenTags.indexOf(root.nodeName.toUpperCase()) !== -1) { removeNode(root); }
slice(root.children).forEach(removeForbiddenTags);
};

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,99 @@
/*
Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #F0F0F0;
}
/* Base color: saturation 0; */
.hljs,
.hljs-subst {
color: #444;
}
.hljs-comment {
color: #888888;
}
.hljs-keyword,
.hljs-attribute,
.hljs-selector-tag,
.hljs-meta-keyword,
.hljs-doctag,
.hljs-name {
font-weight: bold;
}
/* User color: hue: 0 */
.hljs-type,
.hljs-string,
.hljs-number,
.hljs-selector-id,
.hljs-selector-class,
.hljs-quote,
.hljs-template-tag,
.hljs-deletion {
color: #880000;
}
.hljs-title,
.hljs-section {
color: #880000;
font-weight: bold;
}
.hljs-regexp,
.hljs-symbol,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #BC6060;
}
/* Language color: hue: 90; */
.hljs-literal {
color: #78A960;
}
.hljs-built_in,
.hljs-bullet,
.hljs-code,
.hljs-addition {
color: #397300;
}
/* Meta color: hue: 200 */
.hljs-meta {
color: #1f7199;
}
.hljs-meta-string {
color: #4d99bf;
}
/* Misc effects */
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View File

@ -0,0 +1,99 @@
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
}
.hljs-comment,
.hljs-quote {
color: #998;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
color: #333;
font-weight: bold;
}
.hljs-number,
.hljs-literal,
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
color: #008080;
}
.hljs-string,
.hljs-doctag {
color: #d14;
}
.hljs-title,
.hljs-section,
.hljs-selector-id {
color: #900;
font-weight: bold;
}
.hljs-subst {
font-weight: normal;
}
.hljs-type,
.hljs-class .hljs-title {
color: #458;
font-weight: bold;
}
.hljs-tag,
.hljs-name,
.hljs-attribute {
color: #000080;
font-weight: normal;
}
.hljs-regexp,
.hljs-link {
color: #009926;
}
.hljs-symbol,
.hljs-bullet {
color: #990073;
}
.hljs-built_in,
.hljs-builtin-name {
color: #0086b3;
}
.hljs-meta {
color: #999;
font-weight: bold;
}
.hljs-deletion {
background: #fdd;
}
.hljs-addition {
background: #dfd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View File

@ -73,6 +73,7 @@ define([
"Perl perl",
"PHP php",
"Pig pig",
"PowerShell powershell",
"Properties properties",
"Protocol_Buffers protobuf",
"Puppet puppet",

View File

@ -1,6 +1,10 @@
define(['/api/config'], function (ApiConfig) {
var Module = {};
var DEFAULT_MAIN = '/customize/main-favicon.png?' + ApiConfig.requireConf.urlArgs;
var DEFAULT_ALT = '/customize/alt-favicon.png?' + ApiConfig.requireConf.urlArgs;
var isSupported = Module.isSupported = function () {
return typeof(window.Notification) === 'function';
};
@ -10,22 +14,28 @@ define(['/api/config'], function (ApiConfig) {
};
var getPermission = Module.getPermission = function (f) {
f = f || function () {};
Notification.requestPermission(function (permission) {
if (permission === "granted") { f(true); }
else { f(false); }
});
};
var create = Module.create = function (msg, title) {
var create = Module.create = function (msg, title, icon) {
if (!icon) {
var favicon = document.getElementById('favicon');
icon = favicon.getAttribute('data-main-favicon') || DEFAULT_MAIN;
}
return new Notification(title,{
// icon: icon,
icon: icon,
body: msg,
});
};
Module.system = function (msg, title, icon) {
// Let's check if the browser supports notifications
if (!isSupported()) { console.log("Notifications are not supported"); }
if (!isSupported()) { return; /*console.log("Notifications are not supported");*/ }
// Let's check whether notification permissions have already been granted
else if (hasPermission()) {
@ -41,9 +51,6 @@ define(['/api/config'], function (ApiConfig) {
}
};
var DEFAULT_MAIN = '/customize/main-favicon.png?' + ApiConfig.requireConf.urlArgs;
var DEFAULT_ALT = '/customize/alt-favicon.png?' + ApiConfig.requireConf.urlArgs;
var createFavicon = function () {
console.log("creating favicon");
var fav = document.createElement('link');
@ -112,4 +119,4 @@ define(['/api/config'], function (ApiConfig) {
};
return Module;
});
});

View File

@ -10,6 +10,7 @@ define([
'/common/common-realtime.js',
'/common/common-messaging.js',
'/common/common-messenger.js',
'/common/outer/cursor.js',
'/common/outer/chainpad-netflux-worker.js',
'/common/outer/network-config.js',
'/customize/application_config.js',
@ -20,7 +21,7 @@ define([
'/bower_components/nthen/index.js',
'/bower_components/saferphore/index.js',
], function (Sortify, UserObject, ProxyManager, Migrate, Hash, Util, Constants, Feedback, Realtime, Messaging, Messenger,
CpNfWorker, NetConfig, AppConfig,
Cursor, CpNfWorker, NetConfig, AppConfig,
Crypto, ChainPad, Listmap, nThen, Saferphore) {
var Store = {};
@ -59,6 +60,9 @@ define([
obj[key] = data.value;
}
broadcast([clientId], "UPDATE_METADATA");
if (Array.isArray(path) && path[0] === 'profile' && store.messenger) {
store.messenger.updateMyData();
}
onSync(cb);
};
@ -413,6 +417,27 @@ define([
/////////////////////// Store ////////////////////////////////////
//////////////////////////////////////////////////////////////////
// Get or create the user color for the cursor position
var getRandomColor = function () {
var getColor = function () {
return Math.floor(Math.random() * 156) + 70;
};
return '#' + getColor().toString(16) +
getColor().toString(16) +
getColor().toString(16);
};
var getUserColor = function () {
var color = Util.find(store.proxy, ['settings', 'general', 'cursor', 'color']);
if (!color) {
color = getRandomColor();
Store.setAttribute(null, {
attr: ['general', 'cursor', 'color'],
value: color
}, function () {});
}
return color;
};
// Get the metadata for sframe-common-outer
Store.getMetadata = function (clientId, data, cb) {
var disableThumbnails = Util.find(store.proxy, ['settings', 'general', 'disableThumbnails']);
@ -423,6 +448,7 @@ define([
uid: store.proxy.uid,
avatar: Util.find(store.proxy, ['profile', 'avatar']),
profile: Util.find(store.proxy, ['profile', 'view']),
color: getUserColor(),
curvePublic: store.proxy.curvePublic,
},
// "priv" is not shared with other users but is needed by the apps
@ -462,7 +488,7 @@ define([
if (data.password) { pad.password = data.password; }
if (data.channel) { pad.channel = data.channel; }
store.manager.addPad(data.path, pad, function (e) {
if (e) { return void cb({error: "Error while adding the pad:"+ e}); }
if (e) { return void cb({error: e}); }
sendDriveEvent('DRIVE_CHANGE', {
path: ['drive', UserObject.FILES_DATA]
}, clientId);
@ -597,6 +623,7 @@ define([
Store.setDisplayName = function (clientId, value, cb) {
store.proxy[Constants.displayNameKey] = value;
broadcast([clientId], "UPDATE_METADATA");
if (store.messenger) { store.messenger.updateMyData(); }
onSync(cb);
};
@ -796,12 +823,20 @@ define([
password: data.password,
path: data.path
}, cb);
// Let inner know that dropped files shouldn't trigger the popup
postMessage(clientId, "AUTOSTORE_DISPLAY_POPUP", {
stored: true
});
return;
}
} else {
sendDriveEvent('DRIVE_CHANGE', {
path: ['drive', UserObject.FILES_DATA]
}, clientId);
// Let inner know that dropped files shouldn't trigger the popup
postMessage(clientId, "AUTOSTORE_DISPLAY_POPUP", {
stored: true
});
}
onSync(cb);
};
@ -851,6 +886,9 @@ define([
},
pinPads: function (data, cb) { Store.pinPads(null, data, cb); },
friendComplete: function (data) {
if (data.friend && store.messenger && store.messenger.onFriendAdded) {
store.messenger.onFriendAdded(data.friend);
}
postMessage(clientId, "EV_FRIEND_COMPLETE", data);
},
friendRequest: function (data, cb) {
@ -883,72 +921,18 @@ define([
};
Store.messenger = {
getFriendList: function (clientId, data, cb) {
store.messenger.getFriendList(function (e, keys) {
cb({
error: e,
data: keys,
});
});
},
getMyInfo: function (clientId, data, cb) {
store.messenger.getMyInfo(function (e, info) {
cb({
error: e,
data: info,
});
});
},
getFriendInfo: function (clientId, data, cb) {
store.messenger.getFriendInfo(data, function (e, info) {
cb({
error: e,
data: info,
});
});
},
removeFriend: function (clientId, data, cb) {
store.messenger.removeFriend(data, function (e, info) {
cb({
error: e,
data: info,
});
});
},
openFriendChannel: function (clientId, data, cb) {
store.messenger.openFriendChannel(data, function (e) {
cb({ error: e, });
});
},
getFriendStatus: function (clientId, data, cb) {
store.messenger.getStatus(data, function (e, online) {
cb({
error: e,
data: online,
});
});
},
getMoreHistory: function (clientId, data, cb) {
store.messenger.getMoreHistory(data.curvePublic, data.sig, data.count, function (e, history) {
cb({
error: e,
data: history,
});
});
},
sendMessage: function (clientId, data, cb) {
store.messenger.sendMessage(data.curvePublic, data.content, function (e) {
cb({
error: e,
});
});
},
setChannelHead: function (clientId, data, cb) {
store.messenger.setChannelHead(data.curvePublic, data.sig, function (e) {
cb({
error: e
});
});
execCommand: function (clientId, data, cb) {
if (!store.messenger) { return void cb({error: 'Messenger is disabled'}); }
store.messenger.execCommand(data, cb);
}
};
// Cursor
Store.cursor = {
execCommand: function (clientId, data, cb) {
if (!store.cursor) { return void cb ({error: 'Cursor channel is disabled'}); }
store.cursor.execCommand(clientId, data, cb);
}
};
@ -956,7 +940,7 @@ define([
/////////////////////// PAD //////////////////////////////////////
//////////////////////////////////////////////////////////////////
var channels = Store.channels = {};
var channels = Store.channels = store.channels = {};
Store.joinPad = function (clientId, data) {
var isNew = typeof channels[data.channel] === "undefined";
@ -1011,6 +995,9 @@ define([
var conf = {
onReady: function (padData) {
channel.data = padData || {};
if (padData && padData.validateKey && store.messenger) {
store.messenger.storeValidateKey(data.channel, padData.validateKey);
}
postMessage(clientId, "PAD_READY");
},
onMessage: function (user, m, validateKey, isCp) {
@ -1064,12 +1051,12 @@ define([
});
}
};
CpNfWorker.start(conf);
channel.cpNf = CpNfWorker.start(conf);
};
Store.leavePad = function (clientId, data, cb) {
var channel = channels[data.channel];
if (!channel || !channel.wc) { return void cb ({error: 'EINVAL'}); }
channel.wc.leave();
if (!channel || !channel.cpNf) { return void cb ({error: 'EINVAL'}); }
channel.cpNf.stop();
delete channels[data.channel];
cb();
};
@ -1197,6 +1184,7 @@ define([
logLevel: 1,
ChainPad: ChainPad,
classic: true,
network: store.network,
owners: owners
};
var rt = Listmap.create(listmapConfig);
@ -1210,6 +1198,11 @@ define([
}
return rt;
};
Store.loadSharedFolderAnon = function (clientId, data, cb) {
loadSharedFolder(data.id, data.data, function () {
cb();
});
};
Store.addSharedFolder = function (clientId, data, cb) {
Store.userObjectCommand(clientId, {
cmd: 'addSharedFolder',
@ -1242,11 +1235,15 @@ define([
var messengerEventClients = [];
var dropChannel = function (chanId) {
store.messenger.leavePad(chanId);
store.cursor.leavePad(chanId);
if (!Store.channels[chanId]) { return; }
if (Store.channels[chanId].wc) {
Store.channels[chanId].wc.leave('');
if (Store.channels[chanId].cpNf) {
Store.channels[chanId].cpNf.stop();
}
delete Store.channels[chanId];
};
Store._removeClient = function (clientId) {
@ -1258,6 +1255,7 @@ define([
if (messengerIdx !== -1) {
messengerEventClients.splice(messengerIdx, 1);
}
store.cursor.removeClient(clientId);
Object.keys(Store.channels).forEach(function (chanId) {
var chanIdx = Store.channels[chanId].clients.indexOf(clientId);
if (chanIdx !== -1) {
@ -1309,7 +1307,6 @@ define([
}
};
var messengerEventInit = false;
var sendMessengerEvent = function (q, data) {
messengerEventClients.forEach(function (cId) {
postMessage(cId, q, data);
@ -1319,43 +1316,28 @@ define([
if (messengerEventClients.indexOf(clientId) === -1) {
messengerEventClients.push(clientId);
}
if (!messengerEventInit) {
var messenger = store.messenger = Messenger.messenger(store);
messenger.on('message', function (message) {
sendMessengerEvent('CONTACTS_MESSAGE', message);
};
var loadMessenger = function () {
if (AppConfig.availablePadTypes.indexOf('contacts') === -1) { return; }
var messenger = store.messenger = Messenger.messenger(store);
messenger.on('event', function (ev, data) {
sendMessengerEvent('CHAT_EVENT', {
ev: ev,
data: data
});
messenger.on('join', function (curvePublic, channel) {
sendMessengerEvent('CONTACTS_JOIN', {
curvePublic: curvePublic,
channel: channel,
});
});
messenger.on('leave', function (curvePublic, channel) {
sendMessengerEvent('CONTACTS_LEAVE', {
curvePublic: curvePublic,
channel: channel,
});
});
messenger.on('update', function (info, curvePublic) {
sendMessengerEvent('CONTACTS_UPDATE', {
curvePublic: curvePublic,
info: info,
});
});
messenger.on('friend', function (curvePublic) {
sendMessengerEvent('CONTACTS_FRIEND', {
curvePublic: curvePublic,
});
});
messenger.on('unfriend', function (curvePublic) {
sendMessengerEvent('CONTACTS_UNFRIEND', {
curvePublic: curvePublic,
});
});
messengerEventInit = true;
}
});
};
var loadCursor = function () {
store.cursor = Cursor.init(store, function (ev, data, clients) {
clients.forEach(function (cId) {
postMessage(cId, 'CURSOR_EVENT', {
ev: ev,
data: data
});
});
});
};
//////////////////////////////////////////////////////////////////
/////////////////////// Init /////////////////////////////////////
@ -1442,6 +1424,8 @@ define([
});
userObject.fixFiles();
loadSharedFolders(waitFor);
loadMessenger();
loadCursor();
}).nThen(function () {
var requestLogin = function () {
broadcast([], "REQUEST_LOGIN");
@ -1512,7 +1496,7 @@ define([
var hash = data.userHash || data.anonHash || Hash.createRandomHash('drive');
storeHash = hash;
if (!hash) {
throw new Error('[Store.init] Unable to find or create a drive hash. Aborting...');
return void cb({error: '[Store.init] Unable to find or create a drive hash. Aborting...'});
}
// No password for drive
var secret = Hash.getSecrets('drive', hash);
@ -1618,11 +1602,22 @@ define([
* - requestLogin
*/
var initialized = false;
Store.init = function (clientId, data, callback) {
var whenReady = function (cb) {
if (store.returned) { return void cb(); }
setTimeout(function() {
whenReady(cb);
}, 100);
};
Store.init = function (clientId, data, _callback) {
var callback = Util.once(_callback);
if (initialized) {
return void callback({
state: 'ALREADY_INIT',
returned: store.returned
return void whenReady(function () {
callback({
state: 'ALREADY_INIT',
returned: store.returned
});
});
}
initialized = true;
@ -1638,7 +1633,11 @@ define([
if (Object.keys(store.proxy).length === 1) {
Feedback.send("FIRST_APP_USE", true);
}
store.returned = ret;
if (ret && ret.error) {
initialized = false;
} else {
store.returned = ret;
}
callback(ret);
});

View File

@ -45,6 +45,7 @@ define([], function () {
conf = undefined;
var initializing = true;
var stopped = false;
var lastKnownHash;
var messageFromOuter = function () {};
@ -239,6 +240,12 @@ define([], function () {
onOpen(wc, network, firstConnection);
}, function(err) {
console.error(err);
if (onError) {
onError({
type: err && (err.type || err),
loaded: !initializing
});
}
});
};
@ -250,11 +257,13 @@ define([], function () {
});
network.on('reconnect', function () {
if (stopped) { return; }
initializing = true;
connectTo(network, false);
});
network.on('message', function (msg, sender) { // Direct message
if (stopped) { return; }
var wchan = findChannelById(network.webChannels, channel);
if (wchan) {
onMsg(sender, msg, wchan, network, true);
@ -262,6 +271,14 @@ define([], function () {
});
connectTo(network, true);
return {
stop: function () {
var wchan = findChannelById(network.webChannels, channel);
if (wchan) { wchan.leave(''); }
stopped = true;
}
};
};
return {

243
www/common/outer/cursor.js Normal file
View File

@ -0,0 +1,243 @@
define([
'/common/common-util.js',
'/common/common-constants.js',
'/customize/messages.js',
'/bower_components/chainpad-crypto/crypto.js',
], function (Util, Constants, Messages, Crypto) {
var Cursor = {};
var convertToUint8 = function (obj) {
var l = Object.keys(obj).length;
var u = new Uint8Array(l);
for (var i = 0; i<l; i++) {
u[i] = obj[i];
}
return u;
};
// Send the client's cursor to their channel when we receive an update
var sendMyCursor = function (ctx, clientId) {
var client = ctx.clients[clientId];
if (!client || !client.cursor) { return; }
var chan = ctx.channels[client.channel];
if (!chan) { return; }
var data = {
id: client.id,
cursor: client.cursor
};
chan.sendMsg(JSON.stringify(data));
ctx.emit('MESSAGE', data, chan.clients.filter(function (cl) {
return cl !== clientId;
}));
};
// Send all our cursors data when someone remote joins the channel
var sendOurCursors = function (ctx, chan) {
chan.clients.forEach(function (c) {
var client = ctx.clients[c];
if (!client) { return; }
var data = {
id: client.id,
cursor: client.cursor
};
// Send our data to the other users (NOT including the other tabs of the same worker)
chan.sendMsg(JSON.stringify(data));
});
};
var initCursor = function (ctx, obj, client, cb) {
var channel = obj.channel;
var secret = obj.secret;
if (secret.keys.cryptKey) {
secret.keys.cryptKey = convertToUint8(secret.keys.cryptKey);
}
var padChan = secret.channel;
var network = ctx.store.network;
var first = true;
var c = ctx.clients[client];
if (!c) {
c = ctx.clients[client] = {
channel: channel,
padChan: padChan,
cursor: {}
};
} else {
return void cb();
}
var chan = ctx.channels[channel];
if (chan) {
// This channel is already open in another tab
// ==> Set the ID to our client object
if (!c.id) { c.id = chan.wc.myID + '-' + client; }
// ==> Send the cursor position of the other tabs
chan.clients.forEach(function (cl) {
var clientObj = ctx.clients[cl];
if (!clientObj) { return; }
ctx.emit('MESSAGE', {
id: clientObj.id,
cursor: clientObj.cursor
}, [client]);
});
chan.sendMsg(JSON.stringify({join: true, id: c.id}));
// ==> And push the new tab to the list
chan.clients.push(client);
return void cb();
}
var onOpen = function (wc) {
ctx.channels[channel] = ctx.channels[channel] || {};
var chan = ctx.channels[channel];
if (!c.id) { c.id = wc.myID + '-' + client; }
if (chan.clients) {
// If 2 tabs from the same worker have been opened at the same time,
// we have to fix both of them
chan.clients.forEach(function (cl) {
if (ctx.clients[cl] && !ctx.clients[cl].id) {
ctx.clients[cl].id = wc.myID + '-' + cl;
}
});
}
if (!chan.encryptor) { chan.encryptor = Crypto.createEncryptor(secret.keys); }
wc.on('join', function () {
sendOurCursors(ctx, chan);
});
wc.on('leave', function (peer) {
ctx.emit('MESSAGE', {leave: true, id: peer}, chan.clients);
});
wc.on('message', function (cryptMsg) {
var msg = chan.encryptor.decrypt(cryptMsg, secret.keys && secret.keys.validateKey);
var parsed;
try {
parsed = JSON.parse(msg);
if (parsed && parsed.join) {
return void sendOurCursors(ctx, chan);
}
ctx.emit('MESSAGE', parsed, chan.clients);
} catch (e) { console.error(e); }
});
chan.wc = wc;
chan.sendMsg = function (msg, cb) {
cb = cb || function () {};
var cmsg = chan.encryptor.encrypt(msg);
wc.bcast(cmsg).then(function () {
cb();
}, function (err) {
cb({error: err});
});
};
if (!first) { return; }
chan.clients = [client];
first = false;
cb();
};
network.join(channel).then(onOpen, function (err) {
return void cb({error: err});
});
network.on('reconnect', function () {
if (!ctx.channels[channel]) { console.log("cant reconnect", channel); return; }
network.join(channel).then(onOpen, function (err) {
console.error(err);
});
});
};
var updateCursor = function (ctx, data, client, cb) {
var c = ctx.clients[client];
if (!c) { return void cb({error: 'NO_CLIENT'}); }
data.color = Util.find(ctx.store.proxy, ['settings', 'general', 'cursor', 'color']);
data.name = ctx.store.proxy[Constants.displayNameKey] || Messages.anonymous;
data.avatar = Util.find(ctx.store.proxy, ['profile', 'avatar']);
c.cursor = data;
sendMyCursor(ctx, client);
cb();
};
var leaveChannel = function (ctx, padChan) {
// Leave channel and prevent reconnect when we leave a pad
Object.keys(ctx.channels).some(function (cursorChan) {
var channel = ctx.channels[cursorChan];
if (channel.padChan !== padChan) { return; }
if (channel.wc) { channel.wc.leave(); }
delete ctx.channels[cursorChan];
return true;
});
};
// Remove the client from all its channels when a tab is closed
var removeClient = function (ctx, clientId) {
var filter = function (c) {
return c !== clientId;
};
// Remove the client from our channels
var chan;
for (var k in ctx.channels) {
chan = ctx.channels[k];
chan.clients = chan.clients.filter(filter);
if (chan.clients.length === 0) {
if (chan.wc) { chan.wc.leave(); }
delete ctx.channels[k];
}
}
// Send the leave message to the channel we were in
if (ctx.clients[clientId]) {
var leaveMsg = {
leave: true,
id: ctx.clients[clientId].id
};
chan = ctx.channels[ctx.clients[clientId].channel];
if (chan) {
chan.sendMsg(JSON.stringify(leaveMsg));
ctx.emit('MESSAGE', leaveMsg, chan.clients);
}
}
delete ctx.clients[clientId];
};
Cursor.init = function (store, emit) {
var cursor = {};
var ctx = {
store: store,
emit: emit,
channels: {},
clients: {}
};
cursor.removeClient = function (clientId) {
removeClient(ctx, clientId);
};
cursor.leavePad = function (padChan) {
leaveChannel(ctx, padChan);
};
cursor.execCommand = function (clientId, obj, cb) {
var cmd = obj.cmd;
var data = obj.data;
if (cmd === 'INIT_CURSOR') {
return void initCursor(ctx, data, clientId, cb);
}
if (cmd === 'UPDATE') {
return void updateCursor(ctx, data, clientId, cb);
}
};
return cursor;
};
return Cursor;
});

View File

@ -56,19 +56,14 @@ define([
INCREMENT_TEMPLATE_USE: Store.incrementTemplateUse,
GET_SHARED_FOLDER: Store.getSharedFolder,
ADD_SHARED_FOLDER: Store.addSharedFolder,
LOAD_SHARED_FOLDER: Store.loadSharedFolderAnon,
// Messaging
INVITE_FROM_USERLIST: Store.inviteFromUserlist,
ADD_DIRECT_MESSAGE_HANDLERS: Store.addDirectMessageHandlers,
// Messenger
CONTACTS_GET_FRIEND_LIST: Store.messenger.getFriendList,
CONTACTS_GET_MY_INFO: Store.messenger.getMyInfo,
CONTACTS_GET_FRIEND_INFO: Store.messenger.getFriendInfo,
CONTACTS_REMOVE_FRIEND: Store.messenger.removeFriend,
CONTACTS_OPEN_FRIEND_CHANNEL: Store.messenger.openFriendChannel,
CONTACTS_GET_FRIEND_STATUS: Store.messenger.getFriendStatus,
CONTACTS_GET_MORE_HISTORY: Store.messenger.getMoreHistory,
CONTACTS_SEND_MESSAGE: Store.messenger.sendMessage,
CONTACTS_SET_CHANNEL_HEAD: Store.messenger.setChannelHead,
// Chat
CHAT_COMMAND: Store.messenger.execCommand,
// Cursor
CURSOR_COMMAND: Store.cursor.execCommand,
// Pad
SEND_PAD_MSG: Store.sendPadMsg,
JOIN_PAD: Store.joinPad,

View File

@ -386,14 +386,14 @@ define([
if (data.folderData) { return; }
// Folder creation
var hash = Hash.createRandomHash('drive');
var href = '/drive/#' + hash;
var secret = Hash.getSecrets('drive', hash);
var hash = Hash.createRandomHash('drive', data.password);
var secret = Hash.getSecrets('drive', hash, data.password);
var hashes = Hash.getHashes(secret);
folderData = {
href: href,
roHref: '/drive/#' + Hash.getViewHashFromKeys(secret),
href: '/drive/#' + hashes.editHash,
roHref: '/drive/#' + hashes.viewHash,
channel: secret.channel,
ctime: +new Date()
ctime: +new Date(),
};
if (data.password) { folderData.password = data.password; }
if (data.owned) { folderData.owners = [Env.edPublic]; }
@ -541,6 +541,11 @@ define([
// Set the value everywhere the given pad is stored (main and shared folders)
var setPadAttribute = function (Env, data, cb) {
cb = cb || function () {};
if (!data.attr || !data.attr.trim()) { return void cb("E_INVAL_ATTR"); }
var sfId = Env.user.userObject.getSFIdFromHref(data.href);
if (sfId) {
Env.user.proxy[UserObject.SHARED_FOLDERS][sfId][data.attr] = data.value;
}
var datas = findHref(Env, data.href);
var nt = nThen;
datas.forEach(function (d) {
@ -557,6 +562,10 @@ define([
// correct one.
var getPadAttribute = function (Env, data, cb) {
cb = cb || function () {};
var sfId = Env.user.userObject.getSFIdFromHref(data.href);
if (sfId) {
return void cb(null, Env.user.proxy[UserObject.SHARED_FOLDERS][sfId][data.attr]);
}
var datas = findHref(Env, data.href);
var nt = nThen;
var res = {};
@ -584,12 +593,14 @@ define([
};
var getTagsList = function (Env) {
var list = [];
var list = {};
var userObjects = _getUserObjects(Env);
userObjects.forEach(function (uo) {
Array.prototype.push.apply(list, uo.getTagsList());
var l = uo.getTagsList();
Object.keys(l).forEach(function (t) {
list[t] = list[t] ? (list[t] + l[t]) : l[t];
});
});
list = Util.deduplicateString(list);
return list;
};
@ -844,7 +855,8 @@ define([
var getFileData = _getFileData;
var getUserObjectPath = _getUserObjectPath;
var find = function (Env, path) {
var find = function (Env, path, fId) {
if (fId) { return Env.folders[fId].userObject.find(path); }
var resolved = _resolvePath(Env, path);
return resolved.userObject.find(resolved.path);
};

View File

@ -217,6 +217,9 @@ types of messages:
});
});
// network.onHistoryKeeperChange is defined in chainpad-netflux.js
// The function we pass will be called when the drive reconnects and
// chainpad-netflux detects a new history keeper id
if (network.onHistoryKeeperChange) {
network.onHistoryKeeperChange(function () {
send('COOKIE', "", function (e) {

View File

@ -55,6 +55,7 @@ define([
var create = function (options, cb) {
var evContentUpdate = Util.mkEvent();
var evCursorUpdate = Util.mkEvent();
var evEditableStateChange = Util.mkEvent();
var evOnReady = Util.mkEvent(true);
var evOnDefaultContentNeeded = Util.mkEvent();
@ -68,6 +69,7 @@ define([
var cpNfInner;
var readOnly;
var title;
var cursor;
var toolbar;
var state = STATE.DISCONNECTED;
var firstConnection = true;
@ -90,6 +92,7 @@ define([
var textContentGetter;
var titleRecommender = function () { return false; };
var contentGetter = function () { return UNINITIALIZED; };
var cursorGetter;
var normalize0 = function (x) { return x; };
var normalize = function (x) {
@ -180,7 +183,7 @@ define([
if (JSONSortify(newContent) === JSONSortify(oldContent)) { return; }
try {
evContentUpdate.fire(newContent, waitFor);
setTimeout(function () { oldContent = newContent; });
oldContent = newContent;
} catch (e) {
console.log(e.stack);
UI.errorLoadingScreen(e.message);
@ -259,6 +262,9 @@ define([
if (content === UNINITIALIZED) { return; }
throw new Error("Content must be an object or array, type is " + typeof(content));
}
oldContent = content;
if (Array.isArray(content)) {
// Pad
content.push({ metadata: cpNfInner.metadataMgr.getMetadataLazy() });
@ -322,6 +328,17 @@ define([
if (!readOnly) { onLocal(); }
evOnReady.fire(newPad);
common.openPadChat(onLocal);
if (!readOnly && cursorGetter) {
common.openCursorChannel(onLocal);
cursor = common.createCursor();
cursor.onCursorUpdate(function (data) {
var newContentStr = cpNfInner.chainpad.getUserDoc();
var hjson = normalize(JSON.parse(newContentStr));
evCursorUpdate.fire(data, hjson);
});
}
UI.removeLoadingScreen(emitResize);
var privateDat = cpNfInner.metadataMgr.getPrivateData();
@ -559,6 +576,7 @@ define([
}, onLocal);
var configTb = {
displayed: [
'chat',
'userlist',
'title',
'useradmin',
@ -632,6 +650,20 @@ define([
// in the pad when requested by the framework.
setContentGetter: function (cg) { contentGetter = cg; },
// Set the function providing the cursor position when request by the framework.
setCursorGetter: function (cg) {
toolbar.showColors();
cursorGetter = cg;
},
onCursorUpdate: evCursorUpdate.reg,
updateCursor: function () {
if (cursor && cursorGetter) {
var newContentStr = cpNfInner.chainpad.getUserDoc();
var data = normalize(JSON.parse(newContentStr));
cursor.updateCursor(cursorGetter(data));
}
},
// Set a text content supplier, this is a function which will give a text
// representation of the pad content if a text analyzer is configured
setTextContentGetter: function (tcg) { textContentGetter = tcg; },

View File

@ -36,7 +36,8 @@ define([
window.addEventListener('message', onMsg);
}).nThen(function (/*waitFor*/) {
SFCommonO.start({
useCreationScreen: true
useCreationScreen: true,
messaging: true
});
});
});

View File

@ -38,7 +38,14 @@ define([
return cursor;
};
module.getContentExtension = function (mode) {
return (Modes.extensionOf(mode) || '.txt').slice(1);
};
module.fileExporter = function (content) {
return new Blob([ content ], { type: 'text/plain;charset=utf-8' });
};
module.setValueAndCursor = function (editor, oldDoc, remoteDoc) {
editor._noCursorUpdate = true;
var scroll = editor.getScrollInfo();
//get old cursor here
var oldCursor = {};
@ -53,6 +60,7 @@ define([
return TextCursor.transformCursor(oldCursor[attr], ops);
});
editor._noCursorUpdate = false;
if(selects[0] === selects[1]) {
editor.setCursor(posToCursor(selects[0], remoteDoc));
}
@ -271,10 +279,10 @@ define([
};
exp.getContentExtension = function () {
return (Modes.extensionOf(exp.highlightMode) || '.txt').slice(1);
return module.getContentExtension(exp.highlightMode);
};
exp.fileExporter = function () {
return new Blob([ editor.getValue() ], { type: 'text/plain;charset=utf-8' });
return module.fileExporter(editor.getValue());
};
exp.fileImporter = function (content, file) {
var $toolbarContainer = $('#cme_toolbox');
@ -340,6 +348,108 @@ define([
framework._.sfCommon.createFileManager(fmConfig);
};
exp.mkIndentSettings = function (metadataMgr) {
var setIndentation = function (units, useTabs, fontSize) {
if (typeof(units) !== 'number') { return; }
editor.setOption('indentUnit', units);
editor.setOption('tabSize', units);
editor.setOption('indentWithTabs', useTabs);
$('.CodeMirror').css('font-size', fontSize+'px');
};
var indentKey = 'indentUnit';
var useTabsKey = 'indentWithTabs';
var fontKey = 'fontSize';
var updateIndentSettings = function () {
if (!metadataMgr) { return; }
var data = metadataMgr.getPrivateData().settings;
data = data.codemirror || {};
var indentUnit = data[indentKey];
var useTabs = data[useTabsKey];
var fontSize = data[fontKey];
setIndentation(
typeof(indentUnit) === 'number'? indentUnit : 2,
typeof(useTabs) === 'boolean'? useTabs : false,
typeof(fontSize) === 'number' ? fontSize : 12);
};
metadataMgr.onChangeLazy(updateIndentSettings);
updateIndentSettings();
};
exp.getCursor = function () {
var doc = canonicalize(editor.getValue());
var cursor = {};
cursor.selectionStart = cursorToPos(editor.getCursor('from'), doc);
cursor.selectionEnd = cursorToPos(editor.getCursor('to'), doc);
return cursor;
};
var makeCursor = function (id) {
if (document.getElementById(id)) {
return document.getElementById(id);
}
return $('<span>', {
'id': id,
'class': 'cp-codemirror-cursor'
})[0];
};
var makeTippy = function (cursor) {
var html = '<span class="cp-cursor-avatar">';
if (cursor.avatar && UIElements.getAvatar(cursor.avatar)) {
html += UIElements.getAvatar(cursor.avatar);
}
html += cursor.name + '</span>';
return html;
};
var marks = {};
exp.setRemoteCursor = function (data) {
if (data.leave) {
$('.cp-codemirror-cursor[id^='+data.id+']').each(function (i, el) {
var id = $(el).attr('id');
if (marks[id]) {
marks[id].clear();
delete marks[id];
}
});
return;
}
var id = data.id;
var cursor = data.cursor;
var doc = canonicalize(editor.getValue());
if (marks[id]) {
marks[id].clear();
delete marks[id];
}
if (!cursor.selectionStart) { return; }
if (cursor.selectionStart === cursor.selectionEnd) {
var cursorPosS = posToCursor(cursor.selectionStart, doc);
var el = makeCursor(id);
if (cursor.color) {
$(el).css('border-color', cursor.color);
$(el).css('background-color', cursor.color);
}
if (cursor.name) {
$(el).attr('title', makeTippy(cursor));
}
marks[id] = editor.setBookmark(cursorPosS, { widget: el });
} else {
var pos1 = posToCursor(cursor.selectionStart, doc);
var pos2 = posToCursor(cursor.selectionEnd, doc);
var css = cursor.color
? 'background-color: rgba(' + Util.hexToRGB(cursor.color).join(',') + ',0.2)'
: 'background-color: rgba(255,0,0,0.2)';
marks[id] = editor.markText(pos1, pos2, {
css: css,
title: makeTippy(cursor),
className: 'cp-tippy-html'
});
}
};
return exp;
};

View File

@ -0,0 +1,59 @@
define([
'/common/common-util.js',
], function (Util) {
var module = {};
module.create = function (Common) {
var exp = {};
var sframeChan = Common.getSframeChannel();
var metadataMgr = Common.getMetadataMgr();
var privateData = metadataMgr.getPrivateData();
var share = Util.find(privateData, ['settings', 'general', 'cursor', 'share']);
var show = Util.find(privateData, ['settings', 'general', 'cursor', 'show']);
var execCommand = function (cmd, data, cb) {
sframeChan.query('Q_CURSOR_COMMAND', {cmd: cmd, data: data}, function (err, obj) {
if (err || (obj && obj.error)) { return void cb(err || (obj && obj.error)); }
cb(void 0, obj);
});
};
exp.updateCursor = function (obj) {
if (share === false) { return; }
execCommand('UPDATE', obj, function (err) {
if (err) { console.error(err); }
});
};
var messageHandlers = [];
exp.onCursorUpdate = function (handler) {
messageHandlers.push(handler);
};
var onMessage = function (data) {
if (show === false) { return; }
messageHandlers.forEach(function (h) {
try {
h(data);
} catch (e) {
console.error(e);
}
});
};
sframeChan.on('EV_CURSOR_EVENT', function (obj) {
var cmd = obj.ev;
var data = obj.data;
if (cmd === 'MESSAGE') {
onMessage(data);
return;
}
});
return exp;
};
return module;
});

View File

@ -5,12 +5,15 @@ define([
'/common/common-interface.js',
'/common/common-ui-elements.js',
'/common/common-util.js',
'/common/common-hash.js',
'/common/hyperscript.js',
'/customize/messages.js',
'/bower_components/file-saver/FileSaver.min.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
], function ($, FileCrypto, Thumb, UI, UIElements, Util, h, Messages) {
], function ($, FileCrypto, Thumb, UI, UIElements, Util, Hash, h, Messages) {
var Nacl = window.nacl;
var saveAs = window.saveAs;
var module = {};
var blobToArrayBuffer = function (blob, cb) {
@ -41,6 +44,7 @@ define([
var $table = File.$table = $('<table>', { id: 'cp-fileupload-table' });
var $thead = $('<tr>').appendTo($table);
$('<td>').text(Messages.upload_type).appendTo($thead);
$('<td>').text(Messages.upload_name).appendTo($thead);
$('<td>').text(Messages.upload_size).appendTo($thead);
$('<td>').text(Messages.upload_progress).appendTo($thead);
@ -183,6 +187,7 @@ define([
// setTimeout to fix a firefox error 'NS_ERROR_NOT_AVAILABLE'
window.setTimeout(function () { File.$container.show(); });
var file = queue.queue.shift();
if (file.dl) { return void file.dl(file); }
upload(file);
};
queue.push = function (obj) {
@ -192,7 +197,7 @@ define([
// setTimeout to fix a firefox error 'NS_ERROR_NOT_AVAILABLE'
window.setTimeout(function () { $table.show(); });
var estimate = FileCrypto.computeEncryptedSize(obj.blob.byteLength, obj.metadata);
var estimate = obj.dl ? obj.size : FileCrypto.computeEncryptedSize(obj.blob.byteLength, obj.metadata);
var $progressBar = $('<div>', {'class':'cp-fileupload-table-progress-container'});
var $progressValue = $('<span>', {'class':'cp-fileupload-table-progress-value'}).text(Messages.upload_pending);
@ -213,8 +218,9 @@ define([
var $link = $('<a>', {
'class': 'cp-fileupload-table-link',
'rel': 'noopener noreferrer'
}).text(obj.metadata.name);
}).text(obj.dl ? obj.name : obj.metadata.name);
$('<td>').text(obj.dl ? Messages.download_dl : Messages.upload_up).appendTo($tr);
$('<td>').append($link).appendTo($tr);
$('<td>').text(prettySize(estimate)).appendTo($tr);
$('<td>', {'class': 'cp-fileupload-table-progress'}).append($progressBar).append($progressValue).appendTo($tr);
@ -440,8 +446,124 @@ define([
createUploader(config.dropArea, config.hoverArea, config.body);
File.downloadFile = function (fData, cb) {
var parsed = Hash.parsePadUrl(fData.href || fData.roHref);
var hash = parsed.hash;
var name = fData.filename || fData.title;
var secret = Hash.getSecrets('file', hash, fData.password);
var src = Hash.getBlobPathFromHex(secret.channel);
var key = secret.keys && secret.keys.cryptKey;
common.getFileSize(secret.channel, function (e, data) {
var todo = function (file) {
if (queue.inProgress) { return; }
queue.inProgress = true;
var id = file.id;
var $row = $table.find('tr[id="'+id+'"]');
var $pv = $row.find('.cp-fileupload-table-progress-value');
var $pb = $row.find('.cp-fileupload-table-progress-container');
var $pc = $row.find('.cp-fileupload-table-progress');
var $link = $row.find('.cp-fileupload-table-link');
var done = function () {
$row.find('.cp-fileupload-table-cancel').text('-');
queue.inProgress = false;
queue.next();
};
var updateDLProgress = function (progressValue) {
var text = Math.round(progressValue*100) + '%';
text += ' ('+ Messages.download_step1 +'...)';
$pv.text(text);
$pb.css({
width: progressValue * $pc.width()+'px'
});
};
var updateProgress = function (progressValue) {
var text = Math.round(progressValue*100) + '%';
text += progressValue === 1 ? '' : ' ('+ Messages.download_step2 +'...)';
$pv.text(text);
$pb.css({
width: progressValue * $pc.width()+'px'
});
};
var dl = module.downloadFile(fData, function (err, obj) {
$link.prepend($('<span>', {'class': 'fa fa-external-link'}))
.attr('href', '#')
.click(function (e) {
e.preventDefault();
obj.download();
});
done();
if (obj) { obj.download(); }
cb(err, obj);
}, {
src: src,
key: key,
name: name,
progress: updateDLProgress,
progress2: updateProgress,
});
var $cancel = $('<span>', {'class': 'cp-fileupload-table-cancel-button fa fa-times'}).click(function () {
dl.cancel();
$cancel.remove();
$row.find('.cp-fileupload-table-progress-value').text(Messages.upload_cancelled);
done();
});
$row.find('.cp-fileupload-table-cancel').html('').append($cancel);
};
queue.push({
dl: todo,
size: data,
name: name
});
});
};
return File;
};
module.downloadFile = function (fData, cb, obj) {
var cancelled = false;
var cancel = function () {
cancelled = true;
};
var src, key, name;
if (obj && obj.src && obj.key && obj.name) {
src = obj.src;
key = obj.key;
name = obj.name;
} else {
var parsed = Hash.parsePadUrl(fData.href || fData.roHref);
var hash = parsed.hash;
name = fData.filename || fData.title;
var secret = Hash.getSecrets('file', hash, fData.password);
src = Hash.getBlobPathFromHex(secret.channel);
key = secret.keys && secret.keys.cryptKey;
}
Util.fetch(src, function (err, u8) {
if (cancelled) { return; }
if (err) { return void cb('E404'); }
FileCrypto.decrypt(u8, key, function (err, res) {
if (cancelled) { return; }
if (err) { return void cb(err); }
if (!res.content) { return void cb('EEMPTY'); }
var dl = function () {
saveAs(res.content, name || res.metadata.name);
};
cb(null, {
metadata: res.metadata,
content: res.content,
download: dl
});
}, obj && obj.progress2);
}, obj && obj.progress);
return {
cancel: cancel
};
};
return module;
});

View File

@ -21,7 +21,9 @@ define([
var FilePicker;
var Messaging;
var Notifier;
var Utils = {};
var Utils = {
nThen: nThen
};
var AppConfig;
var Test;
var password;
@ -93,6 +95,7 @@ define([
Cryptpad.loading.onDriveEvent.reg(function (data) {
if (sframeChan) { sframeChan.event('EV_LOADING_INFO', data); }
});
Cryptpad.ready(waitFor(function () {
if (sframeChan) {
sframeChan.event('EV_LOADING_INFO', {
@ -204,6 +207,10 @@ define([
// If no password, continue...
todo();
}
}).nThen(function (waitFor) {
if (cfg.afterSecrets) {
cfg.afterSecrets(Cryptpad, Utils, secret, waitFor());
}
}).nThen(function (waitFor) {
// Check if the pad exists on server
if (!window.location.hash) { isNewFile = true; return; }
@ -262,6 +269,7 @@ define([
donateURL: Cryptpad.donateURL,
upgradeURL: Cryptpad.upgradeURL
},
plan: localStorage[Utils.Constants.plan],
isNewFile: isNewFile,
isDeleted: isNewFile && window.location.hash.length > 0,
forceCreationScreen: forceCreationScreen,
@ -272,6 +280,15 @@ define([
if (window.CryptPad_newSharedFolder) {
additionalPriv.newSharedFolder = window.CryptPad_newSharedFolder;
}
if (Utils.Constants.criticalApps.indexOf(parsed.type) === -1 &&
AppConfig.availablePadTypes.indexOf(parsed.type) === -1) {
additionalPriv.disabledApp = true;
}
if (!Utils.LocalStore.isLoggedIn() &&
AppConfig.registeredOnlyTypes.indexOf(parsed.type) !== -1) {
additionalPriv.registeredOnly = true;
}
for (var k in additionalPriv) { metaObj.priv[k] = additionalPriv[k]; }
if (cfg.addData) {
@ -370,7 +387,7 @@ define([
forceSave: true
};
Cryptpad.setPadTitle(data, function (err) {
cb(err);
cb({error: err});
});
});
sframeChan.on('Q_IS_PAD_STORED', function (data, cb) {
@ -420,8 +437,8 @@ define([
Utils.LocalStore.logout(cb);
});
sframeChan.on('EV_NOTIFY', function () {
Notifier.notify();
sframeChan.on('EV_NOTIFY', function (data) {
Notifier.notify(data);
});
sframeChan.on('Q_SET_LOGIN_REDIRECT', function (data, cb) {
@ -640,8 +657,8 @@ define([
initFilePicker(data);
});
sframeChan.on('Q_TEMPLATE_USE', function (href, cb) {
Cryptpad.useTemplate(href, Cryptget, cb);
sframeChan.on('Q_TEMPLATE_USE', function (data, cb) {
Cryptpad.useTemplate(data, Cryptget, cb);
});
sframeChan.on('Q_TEMPLATE_EXIST', function (type, cb) {
Cryptpad.listTemplates(type, function (err, templates) {
@ -706,7 +723,7 @@ define([
Cryptpad.setLanguage(data, cb);
});
sframeChan.on('Q_CONTACTS_CLEAR_OWNED_CHANNEL', function (channel, cb) {
sframeChan.on('Q_CLEAR_OWNED_CHANNEL', function (channel, cb) {
Cryptpad.clearOwnedChannel(channel, cb);
});
sframeChan.on('Q_REMOVE_OWNED_CHANNEL', function (channel, cb) {
@ -739,60 +756,85 @@ define([
Cryptpad.removeLoginBlock(data, cb);
});
var cgNetwork;
var whenCGReady = function (cb) {
if (cgNetwork && cgNetwork !== true) { console.log(cgNetwork); return void cb(); }
setTimeout(function () {
whenCGReady(cb);
}, 500);
};
var i = 0;
sframeChan.on('Q_CRYPTGET', function (data, cb) {
var todo = function () {
data.opts.network = cgNetwork;
Cryptget.get(data.hash, function (err, val) {
cb({
error: err,
data: val
});
}, data.opts);
};
//return void todo();
if (i > 30) {
i = 0;
cgNetwork = undefined;
}
i++;
if (!cgNetwork) {
cgNetwork = true;
return void Cryptpad.makeNetwork(function (err, nw) {
console.log(nw);
cgNetwork = nw;
todo();
});
} else if (cgNetwork === true) {
return void whenCGReady(todo);
}
todo();
});
sframeChan.on('EV_CRYPTGET_DISCONNECT', function () {
if (!cgNetwork) { return; }
cgNetwork.disconnect();
cgNetwork = undefined;
});
if (cfg.addRpc) {
cfg.addRpc(sframeChan, Cryptpad, Utils);
}
sframeChan.on('Q_CURSOR_OPENCHANNEL', function (data, cb) {
Cryptpad.cursor.execCommand({
cmd: 'INIT_CURSOR',
data: {
channel: data,
secret: secret
}
}, cb);
});
Cryptpad.cursor.onEvent.reg(function (data) {
sframeChan.event('EV_CURSOR_EVENT', data);
});
sframeChan.on('Q_CURSOR_COMMAND', function (data, cb) {
Cryptpad.cursor.execCommand(data, cb);
});
if (cfg.messaging) {
sframeChan.on('Q_CONTACTS_GET_FRIEND_LIST', function (data, cb) {
Cryptpad.messenger.getFriendList(cb);
});
sframeChan.on('Q_CONTACTS_GET_MY_INFO', function (data, cb) {
Cryptpad.messenger.getMyInfo(cb);
});
sframeChan.on('Q_CONTACTS_GET_FRIEND_INFO', function (curvePublic, cb) {
Cryptpad.messenger.getFriendInfo(curvePublic, cb);
});
sframeChan.on('Q_CONTACTS_REMOVE_FRIEND', function (curvePublic, cb) {
Cryptpad.messenger.removeFriend(curvePublic, cb);
});
Notifier.getPermission();
sframeChan.on('Q_CONTACTS_OPEN_FRIEND_CHANNEL', function (curvePublic, cb) {
Cryptpad.messenger.openFriendChannel(curvePublic, cb);
sframeChan.on('Q_CHAT_OPENPADCHAT', function (data, cb) {
Cryptpad.messenger.execCommand({
cmd: 'OPEN_PAD_CHAT',
data: {
channel: data,
secret: secret
}
}, cb);
});
sframeChan.on('Q_CONTACTS_GET_STATUS', function (curvePublic, cb) {
Cryptpad.messenger.getFriendStatus(curvePublic, cb);
sframeChan.on('Q_CHAT_COMMAND', function (data, cb) {
Cryptpad.messenger.execCommand(data, cb);
});
sframeChan.on('Q_CONTACTS_GET_MORE_HISTORY', function (opt, cb) {
Cryptpad.messenger.getMoreHistory(opt, cb);
});
sframeChan.on('Q_CONTACTS_SEND_MESSAGE', function (opt, cb) {
Cryptpad.messenger.sendMessage(opt, cb);
});
sframeChan.on('Q_CONTACTS_SET_CHANNEL_HEAD', function (opt, cb) {
Cryptpad.messenger.setChannelHead(opt, cb);
});
Cryptpad.messenger.onMessageEvent.reg(function (data) {
sframeChan.event('EV_CONTACTS_MESSAGE', data);
});
Cryptpad.messenger.onJoinEvent.reg(function (data) {
sframeChan.event('EV_CONTACTS_JOIN', data);
});
Cryptpad.messenger.onLeaveEvent.reg(function (data) {
sframeChan.event('EV_CONTACTS_LEAVE', data);
});
Cryptpad.messenger.onUpdateEvent.reg(function (data) {
sframeChan.event('EV_CONTACTS_UPDATE', data);
});
Cryptpad.messenger.onFriendEvent.reg(function (data) {
sframeChan.event('EV_CONTACTS_FRIEND', data);
});
Cryptpad.messenger.onUnfriendEvent.reg(function (data) {
sframeChan.event('EV_CONTACTS_UNFRIEND', data);
Cryptpad.messenger.onEvent.reg(function (data) {
sframeChan.event('EV_CHAT_EVENT', data);
});
}
@ -921,7 +963,9 @@ define([
// we need to have the owners and expiration time in the first line on the
// server
var cryptputCfg = $.extend(true, {}, rtConfig, {password: password});
Cryptpad.useTemplate(data.template, Cryptget, function () {
Cryptpad.useTemplate({
href: data.template
}, Cryptget, function () {
startRealtime();
cb();
}, cryptputCfg);

View File

@ -23,7 +23,6 @@ define([
var $title;
exp.setToolbar = function (toolbar) {
$title = toolbar && (toolbar.title || toolbar.pageTitle);
console.log('SET TOOLBAR');
};
exp.getTitle = function () { return exp.title; };

View File

@ -9,6 +9,7 @@ define([
'/common/sframe-common-history.js',
'/common/sframe-common-file.js',
'/common/sframe-common-codemirror.js',
'/common/sframe-common-cursor.js',
'/common/metadata-manager.js',
'/customize/application_config.js',
@ -31,6 +32,7 @@ define([
History,
File,
CodeMirror,
Cursor,
MetadataMgr,
AppConfig,
CommonRealtime,
@ -106,6 +108,9 @@ define([
// Title module
funcs.createTitle = callWithCommon(Title.create);
// Cursor
funcs.createCursor = callWithCommon(Cursor.create);
// Files
funcs.uploadFile = callWithCommon(File.uploadFile);
funcs.createFileManager = callWithCommon(File.create);
@ -161,6 +166,48 @@ define([
});
};
// Chat
var padChatChannel;
// common-ui-elements needs to be able to get the chat channel to put it in metadata when
// importing a template
funcs.getPadChat = function () {
return padChatChannel;
};
funcs.openPadChat = function (saveChanges) {
var md = JSON.parse(JSON.stringify(ctx.metadataMgr.getMetadata()));
//if (md.chat) { delete md.chat; } // Old channel without signing key
// NOTE: "chat2" is also used in cryptpad-common's "useTemplate"
var channel = md.chat2 || Hash.createChannelId();
if (!md.chat2) {
md.chat2 = channel;
ctx.metadataMgr.updateMetadata(md);
setTimeout(saveChanges);
}
padChatChannel = channel;
ctx.sframeChan.query('Q_CHAT_OPENPADCHAT', channel, function (err, obj) {
if (err || (obj && obj.error)) { console.error(err || (obj && obj.error)); }
});
};
var cursorChannel;
// common-ui-elements needs to be able to get the cursor channel to put it in metadata when
// importing a template
funcs.getCursorChannel = function () {
return cursorChannel;
};
funcs.openCursorChannel = function (saveChanges) {
var md = JSON.parse(JSON.stringify(ctx.metadataMgr.getMetadata()));
var channel = md.cursor || Hash.createChannelId();
if (!md.cursor) {
md.cursor = channel;
ctx.metadataMgr.updateMetadata(md);
setTimeout(saveChanges);
}
cursorChannel = channel;
ctx.sframeChan.query('Q_CURSOR_OPENCHANNEL', channel, function (err, obj) {
if (err || (obj && obj.error)) { console.error(err || (obj && obj.error)); }
});
};
// CodeMirror
funcs.initCodeMirrorApp = callWithCommon(CodeMirror.create);
@ -171,8 +218,8 @@ define([
ctx.sframeChan.query('Q_LOGOUT', null, cb);
};
funcs.notify = function () {
ctx.sframeChan.event('EV_NOTIFY');
funcs.notify = function (data) {
ctx.sframeChan.event('EV_NOTIFY', data);
};
funcs.setTabTitle = function (newTitle) {
ctx.sframeChan.event('EV_SET_TAB_TITLE', newTitle);
@ -406,6 +453,24 @@ define([
logoutHandlers.push(h);
};
var shortcuts = [];
funcs.addShortcuts = function (w) {
w = w || window;
if (shortcuts.indexOf(w) !== -1) { return; }
shortcuts.push(w);
$(w).keydown(function (e) {
// Ctrl || Meta (mac)
if (e.ctrlKey || (navigator.platform === "MacIntel" && e.metaKey)) {
// Ctrl+E: New pad modal
if (e.which === 69) {
e.preventDefault();
return void funcs.createNewPadModal();
}
// Ctrl+S: prevent default (save)
if (e.which === 83) { return void e.preventDefault(); }
}
});
};
Object.freeze(funcs);
return { create: function (cb) {
@ -465,7 +530,7 @@ define([
});
ctx.sframeChan.on('EV_LOADING_INFO', function (data) {
UI.updateLoadingProgress(data, true);
UI.updateLoadingProgress(data, 'drive');
});
ctx.sframeChan.on('EV_NEW_VERSION', function () {
@ -482,12 +547,35 @@ define([
});
ctx.metadataMgr.onReady(waitFor());
funcs.addShortcuts();
}).nThen(function () {
try {
var feedback = ctx.metadataMgr.getPrivateData().feedbackAllowed;
Feedback.init(feedback);
} catch (e) { Feedback.init(false); }
try {
var forbidden = ctx.metadataMgr.getPrivateData().disabledApp;
if (forbidden) {
UI.alert(Messages.disabledApp, function () {
funcs.gotoURL('/drive/');
}, {forefront: true});
return;
}
var mustLogin = ctx.metadataMgr.getPrivateData().registeredOnly;
if (mustLogin) {
UI.alert(Messages.mustLogin, function () {
funcs.setLoginRedirect(function () {
funcs.gotoURL('/login/');
});
}, {forefront: true});
return;
}
} catch (e) {
console.error("Can't check permissions for the app");
}
ctx.sframeChan.on('EV_LOADING_ERROR', function (err) {
if (err === 'DELETED') {
var msg = Messages.deletedError + '<br>' + Messages.errorRedirectToHome;
@ -517,6 +605,11 @@ define([
UI.alert(Messages.chrome68);
});
funcs.isPadStored(function (err, val) {
if (err || !val) { return; }
UIElements.displayCrowdfunding(funcs);
});
ctx.sframeChan.ready();
cb(funcs);
});

View File

@ -1,121 +0,0 @@
define([], function () {
var MI = {};
MI.create = function (sFrameChan) {
var messenger = {};
var _handlers = {
message: [],
join: [],
leave: [],
update: [],
friend: [],
unfriend: []
};
messenger.on = function (key, f) {
if (!_handlers[key]) { throw new Error('invalid event'); }
_handlers[key].push(f);
};
sFrameChan.on('EV_CONTACTS_MESSAGE', function (data) {
_handlers.message.forEach(function (f) {
f(data);
});
});
sFrameChan.on('EV_CONTACTS_JOIN', function (data) {
_handlers.join.forEach(function (f) {
f(data.curvePublic, data.channel);
});
});
sFrameChan.on('EV_CONTACTS_LEAVE', function (data) {
_handlers.leave.forEach(function (f) {
f(data.curvePublic, data.channel);
});
});
sFrameChan.on('EV_CONTACTS_UPDATE', function (data) {
_handlers.update.forEach(function (f) {
f(data.info, data.curvePublic);
});
});
sFrameChan.on('EV_CONTACTS_FRIEND', function (data) {
_handlers.friend.forEach(function (f) {
f(data.curvePublic);
});
});
sFrameChan.on('EV_CONTACTS_UNFRIEND', function (data) {
_handlers.unfriend.forEach(function (f) {
f(data.curvePublic);
});
});
/*** QUERIES ***/
messenger.getFriendList = function (cb) {
sFrameChan.query('Q_CONTACTS_GET_FRIEND_LIST', null, function (err, data) {
cb(err || data.error, data.data);
});
};
messenger.getMyInfo = function (cb) {
sFrameChan.query('Q_CONTACTS_GET_MY_INFO', null, function (err, data) {
cb(err || data.error, data.data);
});
};
messenger.getFriendInfo = function (curvePublic, cb) {
sFrameChan.query('Q_CONTACTS_GET_FRIEND_INFO', curvePublic, function (err, data) {
cb(err || data.error, data.data);
//cb({ error: err, data: data, });
});
};
messenger.removeFriend = function (curvePublic, cb) {
sFrameChan.query('Q_CONTACTS_REMOVE_FRIEND', curvePublic, function (err, data) {
cb(err || data.error, data.data);
});
};
messenger.openFriendChannel = function (curvePublic, cb) {
sFrameChan.query('Q_CONTACTS_OPEN_FRIEND_CHANNEL', curvePublic, function (err, data) {
cb(err || data.error);
});
};
messenger.getStatus = function (curvePublic, cb) {
sFrameChan.query('Q_CONTACTS_GET_STATUS', curvePublic, function (err, data) {
cb(err || data.error, data.data);
});
};
messenger.getMoreHistory = function (curvePublic, sig, count, cb) {
sFrameChan.query('Q_CONTACTS_GET_MORE_HISTORY', {
curvePublic: curvePublic,
sig: sig,
count: count
}, function (err, data) {
cb(err || data.error, data.data);
});
};
messenger.sendMessage = function (curvePublic, content, cb) {
sFrameChan.query('Q_CONTACTS_SEND_MESSAGE', {
content: content,
curvePublic: curvePublic,
}, function (err, data) {
cb(err || data.error);
});
};
messenger.setChannelHead = function (curvePublic, sig, cb) {
sFrameChan.query('Q_CONTACTS_SET_CHANNEL_HEAD', {
curvePublic: curvePublic,
sig: sig,
}, function (e, data) {
cb(e || data.error);
});
};
messenger.clearOwnedChannel = function (channel, cb) {
sFrameChan.query('Q_CONTACTS_CLEAR_OWNED_CHANNEL', channel, function (e) {
cb(e);
});
};
return messenger;
};
return MI;
});

View File

@ -153,23 +153,15 @@ define({
// Cache is wiped after each new release
'EV_CACHE_PUT': true,
// Contacts
'EV_CONTACTS_MESSAGE': true,
'EV_CONTACTS_JOIN': true,
'EV_CONTACTS_LEAVE': true,
'EV_CONTACTS_UPDATE': true,
'EV_CONTACTS_FRIEND': true,
'EV_CONTACTS_UNFRIEND': true,
'Q_CONTACTS_GET_FRIEND_LIST': true,
'Q_CONTACTS_GET_MY_INFO': true,
'Q_CONTACTS_GET_FRIEND_INFO': true,
'Q_CONTACTS_REMOVE_FRIEND': true,
'Q_CONTACTS_OPEN_FRIEND_CHANNEL': true,
'Q_CONTACTS_GET_STATUS': true,
'Q_CONTACTS_GET_MORE_HISTORY': true,
'Q_CONTACTS_SEND_MESSAGE': true,
'Q_CONTACTS_SET_CHANNEL_HEAD': true,
'Q_CONTACTS_CLEAR_OWNED_CHANNEL': true,
// Chat
'EV_CHAT_EVENT': true,
'Q_CHAT_COMMAND': true,
'Q_CHAT_OPENPADCHAT': true,
// Cursor
'EV_CURSOR_EVENT': true,
'Q_CURSOR_COMMAND': true,
'Q_CURSOR_OPENCHANNEL': true,
// Put one or more entries to the localStore which will go in localStorage.
'EV_LOCALSTORE_PUT': true,
@ -218,9 +210,13 @@ define({
// Refresh the drive when the drive has changed ('change' or 'remove' events)
'EV_DRIVE_CHANGE': true,
'EV_DRIVE_REMOVE': true,
// Set shared folder hash in the address bar
'EV_DRIVE_SET_HASH': true,
// Remove an owned pad from the server
'Q_REMOVE_OWNED_CHANNEL': true,
// Clear an owned pad from the server (preserve metadata)
'Q_CLEAR_OWNED_CHANNEL': true,
// Notifications about connection and disconnection from the network
'EV_NETWORK_DISCONNECT': true,
@ -266,5 +262,10 @@ define({
'Q_IS_PAD_STORED': true,
// Import mediatag from a pad
'Q_IMPORT_MEDIATAG': true
'Q_IMPORT_MEDIATAG': true,
// Ability to get a pad's content from its hash
'Q_CRYPTGET': true,
'EV_CRYPTGET_DISCONNECT': true,
});

View File

@ -5,9 +5,12 @@ define([
'/common/common-ui-elements.js',
'/common/common-interface.js',
'/common/common-hash.js',
'/common/common-util.js',
'/common/common-feedback.js',
'/contacts/messenger-ui.js',
'/customize/messages.js',
], function ($, Config, ApiConfig, UIElements, UI, Hash, Feedback, Messages) {
], function ($, Config, ApiConfig, UIElements, UI, Hash, Util, Feedback,
MessengerUI, Messages) {
var Common;
var Bar = {
@ -147,7 +150,6 @@ define([
};
};
var avatars = {};
var editingUserName = {
state: false
};
@ -160,6 +162,7 @@ define([
}
});
};
var showColors = false;
var updateUserList = function (toolbar, config) {
// Make sure the elements are displayed
var $userButtons = toolbar.userlist;
@ -230,17 +233,19 @@ define([
editUsersNames.forEach(function (data) {
var name = data.name || Messages.anonymous;
var $span = $('<span>', {'class': 'cp-avatar'});
if (data.color && showColors) {
$span.css('border-color', data.color);
}
var $rightCol = $('<span>', {'class': 'cp-toolbar-userlist-rightcol'});
var $nameSpan = $('<span>', {'class': 'cp-toolbar-userlist-name'}).text(name).appendTo($rightCol);
var $nameSpan = $('<span>', {'class': 'cp-toolbar-userlist-name'}).appendTo($rightCol);
var $nameValue = $('<span>', {
'class': 'cp-toolbar-userlist-name-value'
}).text(name).appendTo($nameSpan);
var isMe = data.uid === user.uid;
if (isMe && !priv.readOnly) {
$nameSpan.html('');
var $nameValue = $('<span>', {
'class': 'cp-toolbar-userlist-name-value'
}).text(name).appendTo($nameSpan);
if (!Config.disableProfile) {
var $button = $('<button>', {
'class': 'fa fa-pencil cp-toolbar-userlist-name-edit',
'class': 'fa fa-pencil cp-toolbar-userlist-button',
title: Messages.user_rename
}).appendTo($nameSpan);
$button.hover(function (e) { e.preventDefault(); e.stopPropagation(); });
@ -296,16 +301,24 @@ define([
$('<span>', {'class': 'cp-toolbar-userlist-friend'}).text(Messages.userlist_pending)
.appendTo($rightCol);
} else {
$('<span>', {
'class': 'fa fa-user-plus cp-toolbar-userlist-friend',
$('<button>', {
'class': 'fa fa-user-plus cp-toolbar-userlist-button',
'title': Messages._getKey('userlist_addAsFriendTitle', [
name
])
}).appendTo($rightCol).click(function (e) {
}).appendTo($nameSpan).click(function (e) {
e.stopPropagation();
Common.sendFriendRequest(data.netfluxId);
});
}
} else if (Common.isLoggedIn() && data.curvePublic && friends[data.curvePublic]) {
$('<button>', {
'class': 'fa fa-comments-o cp-toolbar-userlist-button',
'title': Messages.userlist_chat
}).appendTo($nameSpan).click(function (e) {
e.stopPropagation();
Common.openURL('/contacts/');
});
}
if (data.profile) {
$span.addClass('cp-userlist-clickable');
@ -313,13 +326,13 @@ define([
window.open(origin+'/profile/#' + data.profile);
});
}
if (data.avatar && avatars[data.avatar]) {
$span.append(avatars[data.avatar]);
if (data.avatar && UIElements.getAvatar(data.avatar)) {
$span.append(UIElements.getAvatar(data.avatar));
$span.append($rightCol);
} else {
Common.displayAvatar($span, data.avatar, name, function ($img) {
if (data.avatar && $img && $img.length) {
avatars[data.avatar] = $img[0].outerHTML;
UIElements.setAvatar(data.avatar, $img[0].outerHTML);
}
$span.append($rightCol);
});
@ -410,6 +423,75 @@ define([
return $container;
};
var initChat = function (toolbar) {
var $container = $('<div>', {
id: 'cp-app-contacts-container',
'class': 'cp-app-contacts-inapp'
}).prependTo(toolbar.chatContent);
MessengerUI.create($container, Common, toolbar);
};
var createChat = function (toolbar, config) {
if (!config.metadataMgr) {
throw new Error("You must provide a `metadataMgr` to display the chat");
}
if (Config.availablePadTypes.indexOf('contacts') === -1) { return; }
var $content = $('<div>', {'class': 'cp-toolbar-chat-drawer'});
$content.on('drop dragover', function (e) {
e.preventDefault();
e.stopPropagation();
});
var $closeIcon = $('<span>', {"class": "fa fa-window-close cp-toolbar-chat-drawer-close"}).appendTo($content);
//$('<h2>').text(Messages.users).appendTo($content);
//$('<p>', {'class': USERLIST_CLS}).appendTo($content);
toolbar.chatContent = $content;
var $container = $('<span>', {id: 'cp-toolbar-chat-drawer-open', title: Messages.chatButton});
var $button = $('<button>', {'class': 'fa fa-comments'}).appendTo($container);
$('<span>',{'class': 'cp-dropdown-button-title'}).appendTo($button);
toolbar.$leftside.prepend($container);
if (config.$contentContainer) {
config.$contentContainer.prepend($content);
}
var hide = function () {
$content.hide();
$button.removeClass('cp-toolbar-button-active');
config.$contentContainer.removeClass('cp-chat-visible');
};
var show = function () {
if (Bar.isEmbed) { $content.hide(); return; }
$content.show();
$button.addClass('cp-toolbar-button-active');
config.$contentContainer.addClass('cp-chat-visible');
$button.removeClass('cp-toolbar-notification');
};
$closeIcon.click(function () {
Common.setAttribute(['toolbar', 'chat-drawer'], false);
hide();
});
$button.click(function () {
var visible = $content.is(':visible');
if (visible) { hide(); }
else { show(); }
visible = !visible;
Common.setAttribute(['toolbar', 'chat-drawer'], visible);
});
show();
Common.getAttribute(['toolbar', 'chat-drawer'], function (err, val) {
if (val === false || ($(window).height() < 800 || $(window).width() < 800)) {
return void hide();
}
show();
});
initChat(toolbar);
return $container;
};
var createShare = function (toolbar, config) {
if (!config.metadataMgr) {
throw new Error("You must provide a `metadataMgr` to display the userlist");
@ -648,8 +730,12 @@ define([
var privateData = config.metadataMgr.getPrivateData();
var origin = privateData.origin;
var pathname = privateData.pathname;
var href = inDrive.test(pathname) ? origin+'/index.html' : origin+'/drive/';
var buttonTitle = inDrive.test(pathname) ? Messages.header_homeTitle : Messages.header_logoTitle;
var isAnonSF = privateData.newSharedFolder && !privateData.accountName;
var toMain = inDrive.test(pathname) && !isAnonSF;
var href = toMain ? origin+'/index.html' : origin+'/drive/';
var buttonTitle = toMain ? Messages.header_homeTitle : Messages.header_logoTitle;
var $aTag = $('<a>', {
href: href,
@ -776,11 +862,6 @@ define([
},
content: '<span class="fa fa-plus-circle"></span> ' + Messages.creation_appMenuName
});
$(window).keydown(function (e) {
if (e.which === 69 && (e.ctrlKey || (navigator.platform === "MacIntel" && e.metaKey))) {
Common.createNewPadModal();
}
});
var dropdownConfig = {
text: '', // Button initial text
options: pads_options, // Entries displayed in the menu
@ -846,7 +927,7 @@ define([
var initClickEvents = function (toolbar) {
var removeDropdowns = function () {
window.setTimeout(function () {
toolbar.$toolbar.find('.cp-dropdown-content').hide();
$('body').find('.cp-dropdown-content').hide();
});
};
var cancelEditTitle = function (e) {
@ -997,6 +1078,7 @@ define([
// Create the subelements
var tb = {};
tb['userlist'] = createUserList;
tb['chat'] = createChat;
tb['share'] = createShare;
tb['fileshare'] = createFileShare;
tb['title'] = createTitle;
@ -1010,8 +1092,8 @@ define([
tb['useradmin'] = createUserAdmin;
tb['unpinnedWarning'] = createUnpinnedWarning;
var addElement = toolbar.addElement = function (arr, additionnalCfg, init) {
if (typeof additionnalCfg === "object") { $.extend(true, config, additionnalCfg); }
var addElement = toolbar.addElement = function (arr, additionalCfg, init) {
if (typeof additionalCfg === "object") { $.extend(true, config, additionalCfg); }
arr.forEach(function (el) {
if (typeof el !== "string" || !el.trim()) { return; }
if (typeof tb[el] === "function") {
@ -1089,6 +1171,16 @@ define([
}
};
// Show user colors in the userlist only if the app is compatible and if the user
// wants to see the cursors
toolbar.showColors = function () {
if (!config.metadataMgr) { return; }
var privateData = config.metadataMgr.getPrivateData();
var show = Util.find(privateData, ['settings', 'general', 'cursor', 'show']);
if (show === false) { return; }
showColors = true;
};
// On log out, remove permanently the realtime elements of the toolbar
Common.onLogout(function () {
failed();

View File

@ -0,0 +1,129 @@
# Adding Translations
To illustrate the process of translating, this guide will make an english-pirate translation of Cryptpad.
We'll assume that you have a work locally-installed, properly functioning installation of Cryptpad.
If you don't have Cryptpad installed locally, start by following the steps in the main readme.
## Getting started
Once everything is working, copy the default (English) source file (`/www/common/translations/messages.js`) to a file named according to your language's [ISO 639-1 Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), like `/www/common/translations/messages.fr.js`.
There is no ISO 639-1 language code for _English-pirate_, so we'll just call it `messages.pirate.js`.
```Bash
cd www/common/translations/
cp messages.js messages.pirate.js
```
## Including your translation
To include your translation in the list, you'll need to add it to `/customize.dist/messages.js`.
There are comments indicating what to modify in three places:
```javascript
(function () {
// add your module to this map so it gets used
// please use the translated name of your language ("Français" and not "French")
var map = {
'fr': 'Français',
'es': 'Español',
'pl': 'Polski',
'de': 'Deutsch',
'pt-br': 'Português do Brasil',
'ro': 'Română',
'zh': '繁體中文',
'el': 'Ελληνικά',
};
```
We need to modify that map to include our translation:
```javascript
(function () {
// add your module to this map so it gets used
// please use the translated name of your language ("Français" and not "French")
var map = {
'fr': 'Français',
'es': 'Español',
'pl': 'Polski',
'de': 'Deutsch',
'pt-br': 'Português do Brasil',
'ro': 'Română',
'zh': '繁體中文',
'el': 'Ελληνικά',
'pirate': 'English Pirate', // add our module to the map of languages
};
```
Just add your module in a similar fashion to the existing translations, save your changes, and close `/customize.dist/messages.js`.
You also need to add a customizable version of you translation. To do so, make a copy of the file `/customize.dist/translations/messages.js` with your translation name (`messages.pirate.js` in our case), and change its content to load the correct language file:
```javascript
/*
* You can override the translation text using this file.
* The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js)
in a 'customize' directory (/customize/translations/messages.{LANG}.js).
* If you want to check all the existing translation keys, you can open the internal language file
but you should not change it directly (/common/translations/messages.{LANG}.js)
*/
define(['/common/translations/messages.pirate.js'], function (Messages) { // Change the file name here
// Replace the existing keys (in your copied file) here:
// Messages.button_newpad = "New Rich Text Document";
return Messages;
});
```
That's all!
## Actually translating content
Now we can go back to our file, `/www/common/translations/messages.pirate.js` and start to add our Pirate-language customizations.
Open the translation file you created in `/customize.dist/translations/`.
You should see something like:
```javascript
define(function () {
var out = {};
out.main_title = "Cryptpad: Zero Knowledge, Collaborative Real Time Editing";
```
Now you just need to work through this file, updating the strings like so:
```javascript
define(function () {
var out = {};
out.main_title = "Cryptpad: Knowledge lost at sea while ye scribble with yer mateys";
```
It's important that you modify just the string, and not the variable name which is used to access its content.
For instance, changing `main_title` to `mainTitle` would make the translated string inaccessible to the rest of the codebase.
If a key is not found in your translation, the default English version of that key will be used.
This is to make sure that buttons and other interface elements are not empty, but it's obviously not ideal.
## Verifying Your Translations
It's advisable to save your translation file frequently, and reload Cryptpad in your browser to check that there are no errors in your translation file.
If there are any errors in your code, the file will fail to parse, and the page will no load correctly.
Checking frequently will make it easier to know which change caused the error.
Additionally, we advise using the apps and visiting the various pages, to make sure that your translations make sense in context.
When you're happy with your translation file, you can visit http://localhost:3000/assert/translations/ to view Cryptpad's tests.
These tests will check to make sure that your translation has an entry for every entry in the default English translation.
## Getting Help
If you have any issues, reach out via any of the methods listed in the readme under **Contacting Us**.
We're happy to help.
## Deleting a translation
When a key is nolonger used (such as presentSuccess) you can delete it using this bash one-liner.
```shell
( export KEY=presentSuccess && grep -nr "$KEY" ./www/common/translations/ | sed 's/:.*$//' | while read x; do sed -i -e "/out\.$KEY =/d" $x; done )
```

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,783 @@
/*
* This is an internal language file.
* If you want to change some translations in your CryptPad instance, use the '/customize/translations/messages.{LANG}.js'
* file (make a copy from /customize.dist/translations/messages.{LANG}.js)
*/
define(function () {
var out = {};
out.main_title = "CryptPad: Zero Knowledge, συνεργατική επεξεργασία σε πραγματικό χρόνο";
out.main_slogan = "Ισχύς εν τη ενώσει - Η συνεργασία είναι η λύση"; // TODO remove?
out.type = {};
out.type.pad = 'Εμπλουτισμένο κείμενο';
out.type.code = 'Κώδικας';
out.type.poll = 'Δημοσκόπηση';
out.type.slide = 'Παρουσίαση';
out.type.drive = 'Αποθηκευτικός χώρος';
out.type.whiteboard = 'Πίνακας σχεδιασμού';
out.type.file = 'Αρχείο';
out.type.media = 'Πολυμέσα';
out.type.todo = "Εργασίες";
out.type.contacts = 'Επαφές';
out.button_newpad = 'Νέο pad εμπλουτισμένου κειμένου';
out.button_newcode = 'Νέο pad κώδικα';
out.button_newpoll = 'Νέα δημοσκόπηση';
out.button_newslide = 'Νέα παρουσίαση';
out.button_newwhiteboard = 'Νέος πίνακας';
// NOTE: We want to update the 'common_connectionLost' key.
// Please do not add a new 'updated_common_connectionLostAndInfo' but change directly the value of 'common_connectionLost'
out.updated_0_common_connectionLost = "<b>Η σύνδεση με τον διακομιστή χάθηκε</b><br>Βρίσκεστε σε λειτουργία ανάγνωσης μόνο μέχρι να επανέλθει η σύνδεση.";
out.common_connectionLost = out.updated_0_common_connectionLost;
out.websocketError = 'Αδυναμία σύνδεσης στον διακομιστή...';
out.typeError = "Αυτό το pad δεν είναι συμβατό με την επιλεγμένη εφαρμογή";
out.onLogout = 'Έχετε αποσυνδεθεί, {0}κάντε "κλικ" εδώ{1} για να συνδεθείτε<br>ή πατήστε <em>Escape</em> για να προσπελάσετε το έγγραφο σε λειτουργία ανάγνωσης μόνο.';
out.wrongApp = "Αδυναμία προβολής του περιεχομένου αυτής της συνεδρίας στον περιηγητή σας. Παρακαλώ δοκιμάστε επαναφόρτωση της σελίδας.";
out.loading = "Φόρτωση...";
out.error = "Σφάλμα";
out.saved = "Αποθηκεύτηκε";
out.synced = "Όλα έχουν αποθηκευτεί";
out.deleted = "Το έγγραφο διαγράφηκε από τον αποθηκευτικό σας χώρο";
out.realtime_unrecoverableError = "Η μηχανή πραγματικού χρόνου αντιμετώπισε κάποιο ανεπανόρθωτο σφάλμα. Πατήστε OK για επαναφόρτωση.";
out.disconnected = 'Έγινε αποσύνδεση';
out.synchronizing = 'Γίνεται συγχρονισμός';
out.reconnecting = 'Γίνεται επανασύνδεση...';
out.typing = "Γίνεται επεξεργασία";
out.initializing = "Γίνεται προετοιμασία...";
out.forgotten = 'Μετακινήθηκε στον κάδο ανακύκλωσης';
out.errorState = 'Κρίσιμο σφάλμα: {0}';
out.lag = 'Αργή σύνδεση';
out.readonly = 'Λειτουργία ανάγνωσης μόνο';
out.anonymous = "Ανώνυμος/η";
out.yourself = "Ο εαυτός σας";
out.anonymousUsers = "Ανώνυμοι συντάκτες";
out.anonymousUser = "Ανώνυμος συντάκτης";
out.users = "Χρήστες";
out.and = "Και";
out.viewer = "Θεατής";
out.viewers = "Θεατές";
out.editor = "Συντάκτης";
out.editors = "Συντάκτες";
out.userlist_offline = "Είσαστε προς το παρόν εκτός σύνδεσης, η λίστα χρηστών δεν είναι διαθέσιμη.";
out.language = "Γλώσσα";
out.comingSoon = "Έρχεται σύντομα...";
out.newVersion = '<b>To CryptPad αναβαθμίστηκε!</b><br>' +
'Δείτε τι καινούριο υπάρχει στην πιο πρόσφατη έκδοση:<br>'+
'<a href="https://github.com/xwiki-labs/cryptpad/releases/tag/{0}" target="_blank">Σημειώσεις κυκλοφορίας του CryptPad {0}</a>';
out.upgrade = "Αναβάθμιση";
out.upgradeTitle = "Αναβαθμίστε τον λογαριασμό σας για να αυξήσετε το όριο αποθηκευτικού χώρου";
out.upgradeAccount = "Αναβάθμιση λογαριασμού";
out.MB = "MB";
out.GB = "GB";
out.KB = "KB";
out.supportCryptpad = "Υποστηρίξτε το CryptPad";
out.formattedMB = "{0} MB";
out.formattedGB = "{0} GB";
out.formattedKB = "{0} KB";
out.greenLight = "Όλα λειτουργούν σωστά";
out.orangeLight = "Η αργή σύνδεση ίσως έχει αντίκτυπο στην διάδραση";
out.redLight = "Έχετε αποσυνδεθεί από τη συνεδρία";
out.pinLimitReached = "Έχετε φτάσει το όριο αποθηκευτικού χώρου";
out.updated_0_pinLimitReachedAlert = "Έχετε φτάσει το όριο αποθηκευτικού χώρου. Τα νέα pads δεν θα αποθηκευτούν στο CryptDrive σας.<br>" +
'Μπορείτε είτε να διαγράψετε αρχεία από το CryptDrive σας, είτε να <a href="https://accounts.cryptpad.fr/#!on={0}" target="_blank">αναβαθμισετε τον λογαριασμό σας</a> για να αυξήσετε το όριο αποθήκευσης.';
out.pinLimitReachedAlert = out.updated_0_pinLimitReachedAlert;
out.pinLimitReachedAlertNoAccounts = out.pinLimitReached;
out.pinLimitNotPinned = "Έχετε φτάσει το όριο αποθηκευτικού χώρου.<br>"+
"Αυτό το pad δεν θα αποθηκευτεί στο CryptDrive σας.";
out.pinLimitDrive = "Έχετε φτάσει το όριο αποθηκευτικού χώρου.<br>" +
"Δεν μπορείτε να δημιουργήσετε νέα pads.";
out.moreActions = "Περισσότερες επιλογές";
out.importButton = "Εισαγωγή";
out.importButtonTitle = 'Εισάγετε ένα pad από τοπικό αρχείο';
out.exportButton = "Εξαγωγή";
out.exportButtonTitle = 'Εξάγετε αυτό το pad σε τοπικό αρχείο';
out.exportPrompt = 'Πως θα θέλατε να ονομάσετε το αρχείο σας;';
out.changeNamePrompt = 'Αλλάξτε το όνομα σας (αφήστε το κενό για ανωνυμία): ';
out.user_rename = "Αλλαγή εμφανιζόμενου ονόματος";
out.user_displayName = "Εμφανιζόμενο όνομα";
out.user_accountName = "Όνομα χρήστη";
out.clickToEdit = "Κάντε \"κλικ\" για επεξεργασία";
out.saveTitle = "Αποθήκευση τίτλου (enter)";
out.forgetButton = "Διαγραφή";
out.forgetButtonTitle = 'Μετακίνηση αυτού του pad στον κάδο';
out.forgetPrompt = 'Πατώντας OK θα μετακινηθεί αυτό το pad στον κάδο ανακύκλωσης. Είστε σίγουρος;';
out.movedToTrash = 'Το pad μετακινήθηκε στον κάδο.<br><a href="/drive/">Μεταφερθείτε στο CryptDrive σας</a>';
out.shareButton = 'Διαμοιρασμός';
out.shareSuccess = 'Ο σύνδεσμος αντιγράφηκε στην προσωρινή μνήμη';
out.userListButton = "Λίστα χρηστών";
out.userAccountButton = "Ο λογαριασμός σας";
out.newButton = 'Νέο';
out.newButtonTitle = 'Δημιουργία νέου pad';
out.uploadButton = 'Μεταφόρτωση αρχείου';
out.uploadButtonTitle = 'Μεταφόρτωση νέου αρχείου στον τρέχοντα φάκελο';
out.saveTemplateButton = "Αποθήκευση ως πρότυπο";
out.saveTemplatePrompt = "Επιλέξτε τίτλο για αυτό το πρότυπο";
out.templateSaved = "Το πρότυπο αποθηκεύτηκε!";
out.selectTemplate = "Επιλέξτε ένα πρότυπο ή πατήστε escape";
out.useTemplate = "Έχετε διαθέσιμα πρότυπα για αυτό το είδος pad. Θα θέλετε να χρησιμοποιήσετε κάποιο;"; //Would you like to "You have available templates for this type of pad. Do you want to use one?";
out.useTemplateOK = 'Επιλέξτε ένα πρότυπο (Enter)';
out.useTemplateCancel = 'Ξεκινήστε από το μηδέν (Esc)';
out.previewButtonTitle = "Προβολή ή απόκρυψη προεπισκόπησης της μορφοποίησης Markdown";
out.presentButtonTitle = "Είσοδος σε λειτουργία παρουσίασης";
out.backgroundButtonTitle = 'Αλλάξτε το χρώμα παρασκηνίου στην παρουσίαση';
out.colorButtonTitle = 'Αλλάξτε το χρώμα κειμένου στην λειτουργία παρουσίασης';
out.printText = "Εκτύπωση";
out.printButton = "Εκτύπωση (enter)";
out.printButtonTitle = "Εκτυπώστε τις διαφάνειές σας ή εξάγετε τες ως αρχείο PDF";
out.printOptions = "Επιλογές διάταξης";
out.printSlideNumber = "Εμφάνιση του αριθμού διαφάνειας";
out.printDate = "Εμφάνιση της ημερομηνίας";
out.printTitle = "Εμφάνιση του τίτλου του pad";
out.printCSS = "Προσαρμοσμένες ρυθμίσεις εμφάνισης (CSS):";
out.printTransition = "Ενεργοποίηση κινούμενων μεταβάσεων";
out.filePickerButton = "Ενσωμάτωση αρχείου από το CryptDrive σας";
out.filePicker_close = "Κλείσιμο";
out.filePicker_description = "Επιλέξτε ένα αρχείο από το CryptDrive σας για ενσωμάτωση ή μεταφορτώστε ένα καινούριο";
out.filePicker_filter = "Προβολή αρχείων κατά όνομα";
out.or = 'ή';
out.tags_title = "Ετικέτες (για εσάς μόνο)";
out.tags_add = "Ενημερώστε τις ετικέτες αυτής της σελίδας";
out.tags_searchHint = "Βρείτε αρχεία από τις ετικέτες τους ψάχνωντας στο CryptDrive σας";
out.tags_searchHint = "Ξεκινήστε μια αναζήτηση με το σύμβολο # στο CryptDrive σας για να βρείτε pads με ετικέτες.";
out.tags_notShared = "Οι ετικέτες σας δεν μοιράζονται με άλλους χρήστες";
out.tags_duplicate = "Διπλή ετικέτα: {0}";
out.tags_noentry = "Δεν μπορείτε να βάλετε ετικέτα σε διεγραμένο pad!";
out.slideOptionsText = "Επιλογές";
out.slideOptionsTitle = "Προσαρμόστε τις διαφάνειες σας";
out.slideOptionsButton = "Αποθήκευση (enter)";
out.slide_invalidLess = "Μη έγκυρη προσαρμογή";
out.languageButton = "Γλώσσα";
out.languageButtonTitle = "Επιλέξτε τη γλώσσα που θα χρησιμοποιήσετε για την επισήμανση σύνταξης";
out.themeButton = "Θέμα";
out.themeButtonTitle = "Επιλέξτε το θέμα που θα χρησιμοποιήσετε για την επεξεργασία κώδικα και διαφανειών";
out.editShare = "Σύνδεσμος επεξεργασίας";
out.editShareTitle = "Αντιγραφή του συνδέσμου επεξεργασίας στην προσωρινή μνήμη";
out.editOpen = "Άνοιγμα του συνδέσμου επεξεργασίας σε νέα καρτέλα";
out.editOpenTitle = "Άνοιγμα αυτού του pad για επεξεργασία σε νέα καρτέλα";
out.viewShare = "Σύνδεσμος μόνο για ανάγνωση";
out.viewShareTitle = "Αντιγραφή του συνδέσμου μόνο για ανάγνωση στην προσωρινή μνήμη";
out.viewOpen = "Άνοιγμα του συνδέσμου μόνο για ανάγνωση σε νέα καρτέλα";
out.viewOpenTitle = "Άνοιγμα αυτού του pad μόνο για ανάγνωση σε νέα καρτέλα";
out.fileShare = "Αντιγραφή συνδέσμου";
out.getEmbedCode = "Κώδικας ενσωμάτωσης";
out.viewEmbedTitle = "Ενσωματώστε αυτό το pad σε μία εξωτερική σελίδα";
out.viewEmbedTag = "Για να ενσωματώσετε αυτό το pad, συμπεριλάβετε αυτό το iframe στη σελίδα σας, στο σημείο που θέλετε. Μπορείτε να το διαμορφώσετε χρησιμοποιώντας CSS η HTML παραμέτρους.";
out.fileEmbedTitle = "Ενσωματώστε το αρχείο σε μια εξωτερική σελίδα";
out.fileEmbedScript = "Για να ενσωματώσετε αυτό το αρχείο, συμπεριλάβετε αυτό το script στη σελίδα σας για να φορτωθεί το Media Tag:";
out.fileEmbedTag = "Έπειτα τοποθετήστε αυτό το Media Tag στο σημείο της σελίδας που επιθυμείτε να γίνει ενσωμάτωση:";
out.notifyJoined = "Ο/Η {0} εισήλθε στη συνεργατική συνεδρία";
out.notifyRenamed = "Ο/Η {0} είναι τώρα γνωστός/η ως {1}";
out.notifyLeft = "Ο/Η {0} αποχώρησε από τη συνεργατική συνεδρία";
out.okButton = 'OK (enter)';
out.cancel = "Ακύρωση";
out.cancelButton = 'Ακύρωση (esc)';
out.doNotAskAgain = "Να μην ρωτηθώ ξανά (Esc)";
out.historyText = "Ιστορικό";
out.historyButton = "Εμφάνιση ιστορικού του εγγράφου";
out.history_next = "Μετάβαση στην επόμενη έκδοση";
out.history_prev = "Μετάβαση στην προηγούμενη έκδοση";
out.history_goTo = "Μετάβαση στην επιλεγμένη έκδοση";
out.history_close = "Επιστροφή";
out.history_closeTitle = "Κλείσιμο ιστορικού";
out.history_restore = "Επαναφορά";
out.history_restoreTitle = "Επαναφορά της επιλεγμένης έκδοσης του εγγράφου";
out.history_restorePrompt = "Είστε σίγουροι πως θέλετε να αντικαταστήσετε την τρέχουσα έκδοση του εγγράφου με την επιλεγμένη;";
out.history_restoreDone = "Έγινε επαναφορά του εγγράφου";
out.history_version = "Έκδοση:";
// Ckeditor
out.openLinkInNewTab = "Άνοιγμα συνδέσμου σε νέα καρτέλα";
out.pad_mediatagTitle = "Ρυθμίσεις Media-Tag";
out.pad_mediatagWidth = "Πλάτος (px)";
out.pad_mediatagHeight = "Ύψος (px)";
// Polls
out.poll_title = "Zero Knowledge επιλογή ημερομηνίας";
out.poll_subtitle = "Zero Knowledge, <em>πραγματικού χρόνου</em> οργάνωση";
out.poll_p_save = "Οι ρυθμίσεις σας ενημερώνονται άμεσα, έτσι δεν χρειάζεται ποτέ να αποθηκεύσετε.";
out.poll_p_encryption = "Όλο το περιεχόμενο είναι κρυπτογραφημένο και έτσι μόνο τα άτομα που έχουν τον σύνδεσμο μπορούν να έχουν πρόσβαση σε αυτό. Ούτε ο διακομιστής δεν μπορεί να δει τι γράφετε.";
out.wizardLog = "Πατήστε το κουμπί πάνω αριστερά για να επιστρέψετε στη δημοσκόπηση σας";
out.wizardTitle = "Χρησιμοποιήστε τον οδηγό για να δημιουργήσετε τη δημοσκόπηση σας";
out.wizardConfirm = "Είσαστε έτοιμοι να προσθέσετε αυτές τις επιλογές στη δημοσκόπηση σας;";
out.poll_publish_button = "Δημοσίευση";
out.poll_admin_button = "Διαχείριση";
out.poll_create_user = "Προσθέστε έναν νέο χρήστη";
out.poll_create_option = "Προσθέστε μια νέα επιλογή";
out.poll_commit = "Υποβολή";
out.poll_closeWizardButton = "Κλείσιμο οδηγού";
out.poll_closeWizardButtonTitle = "Κλείσιμο οδηγού";
out.poll_wizardComputeButton = "Υπολογισμός επιλογών";
out.poll_wizardClearButton = "Εκκαθάριση πεδίων";
out.poll_wizardDescription = "Αυτόματα δημιουργήστε έναν αριθμό επιλογών εισάγοντας όσες ημερομηνίες και χρόνους θέλετε";
out.poll_wizardAddDateButton = "+ Ημερομηνίες";
out.poll_wizardAddTimeButton = "+ Χρόνους";
out.poll_optionPlaceholder = "Επιλογή";
out.poll_userPlaceholder = "Το όνομα σας";
out.poll_removeOption = "Είστε σίγουροι πως θέλετε να αφαιρέσετε αυτή την επιλογή;";
out.poll_removeUser = "Είστε σίγουροι πως θέλετε να αφαιρέσετε αυτόν τον χρήστη;";
out.poll_titleHint = "Τίτλος";
out.poll_descriptionHint = "Περιγράψτε τη δημοσκόπηση σας και χρησιμοποιήστε το κουμπί ✓ (δημοσίευση) όταν έχετε τελειώσει.\n" +
"Η περιγραφή μπορεί να γραφτεί χρησιμοποιώντας μορφοποίηση markdown και μπορείτε να ενσωματώσετε γραφικά στοιχεία από το CryptDrive σας.\n" +
"Οποιοσδήποτε με τον σύνδεσμο της δημοσκόπησης μπορεί να αλλάξει την περιγραφή, αλλά αυτό δεν συνίσταται.";
out.poll_remove = "Αφαίρεση";
out.poll_edit = "Επεξεργασία";
out.poll_locked = "Κλείδωμα";
out.poll_unlocked = "Ξεκλείδωμα";
out.poll_show_help_button = "Εμφάνιση βοήθειας";
out.poll_hide_help_button = "Απόκρυψη βοήθειας";
out.poll_bookmark_col = 'Αποθηκεύστε αυτή τη στήλη ώστε να είναι πάντα ξεκλείδωτη και εμφανής κατά την εκκίνηση για εσάς';
out.poll_bookmarked_col = 'Αυτή είναι η στήλη σελιδοδεικτών σας. Θα είναι πάντα ξεκλείδωτη και εμφανής κατά την εκκίνηση για εσάς.';
out.poll_total = 'Σύνολο';
out.poll_comment_list = "Σχόλια";
out.poll_comment_add = "Κάντε ένα σχόλιο";
out.poll_comment_submit = "Αποστολή";
out.poll_comment_remove = "Διαγράψτε αυτό το σχόλιο";
out.poll_comment_placeholder = "Το σχόλιό σας";
out.poll_comment_disabled = "Δημοσιεύστε αυτή τη δημοσκόπηση χρησημοποιώντας το κουμπί ✓ για να ενεργοποιηθεί ο σχολιασμός.";
// Canvas
out.canvas_clear = "Εκκαθάριση";
out.canvas_delete = "Διαγραφή επιλογής";
out.canvas_disable = "Απενεργοποίηση σχεδιασμού";
out.canvas_enable = "Ενεργοποίηση σχεδιασμού";
out.canvas_width = "Πλάτος";
out.canvas_opacity = "Αδιαφάνεια";
out.canvas_opacityLabel = "Αδιαφάνεια: {0}";
out.canvas_widthLabel = "Πλάτος: {0}";
out.canvas_saveToDrive = "Αποθηκεύστε αυτή την εικόνα ως αρχείο στο CryptDrive σας";
out.canvas_currentBrush = "Τρέχων πινέλο";
out.canvas_chooseColor = "Επιλογή χρώματος";
out.canvas_imageEmbed = "Εισάγετε μια εικόνα από τον υπολογιστή σας";
// Profile
out.profileButton = "Προφίλ"; // dropdown menu
out.profile_urlPlaceholder = 'Διεύθυνση';
out.profile_namePlaceholder = 'Το όνομα που θα εμφανίζετε στο προφίλ σας';
out.profile_avatar = "Αβατάρ";
out.profile_upload = " Μεταφορτώστε ένα νέο αβατάρ";
out.profile_uploadSizeError = "Σφάλμα: το αβατάρ σας πρέπει να είναι μικρότερο από {0}";
out.profile_uploadTypeError = "Σφάλμα: αυτό το είδος αρχείου δεν επιτρέπεται. Επιτρεπόμενα αρχεία: {0}";
out.profile_error = "Σφάλμα κατά τη δημιουργία του προφίλ σας: {0}";
out.profile_register = "Πρέπει να εγγραφείτε για να δημιουργήσετε προφίλ!";
out.profile_create = "Δημιουργήστε προφίλ";
out.profile_description = "Περιγραφή";
out.profile_fieldSaved = 'Η καινούρια καταχώρηση αποθηκεύτηκε: {0}';
out.profile_inviteButton = "Σύνδεση";
out.profile_inviteButtonTitle ='Δημιουργήστε έναν σύνδεσμο για να προσκαλέσετε αυτόν το χρήστη να συνδεθεί μαζί σας.';
out.profile_inviteExplanation = "Πατώντας <strong>OK</strong> θα δημιουργηθεί ένας σύνδεσμος προς μια ασφαλή συνεδρία επικοινωνίας όπου <em>μόνο ο/η {0} θα μπορεί να ανοίξει.</em><br><br>Ο σύνδεσμος θα αντιγραφεί στην προσωρινή μνήμη και μπορεί να διαμοιραστεί δημόσια.";
out.profile_viewMyProfile = "Προβολή του προφίλ μου";
// contacts/userlist
out.userlist_addAsFriendTitle = 'Προσθήκη του/της "{0}" ως επαφή';
out.userlist_thisIsYou = 'Αυτός είστε εσείς ("{0}")';
out.userlist_pending = "Εκρεμμεί...";
out.contacts_title = "Επαφές";
out.contacts_addError = 'Σφάλμα κατά την προσθήκη αυτής της επαφής στη λίστα';
out.contacts_added = 'Η επαφή αποδέχτηκε την πρόσκληση.';
out.contacts_rejected = 'Η επαφή απέρριψε την πρόσκληση';
out.contacts_request = 'Ο/Η <em>{0}</em> Θα ήθελε να σας προσθέσει ως επαφή. <b>Αποδοχή<b>;';
out.contacts_send = 'Αποστολή';
out.contacts_remove = 'Αφαίρεση αυτής της επαφής';
out.contacts_confirmRemove = 'Είσαστε σίγουροι πως θέλετε να αφαιρέσετε τον/την <em>{0}</em> από τις επαφές σας;';
out.contacts_typeHere = "Πληκτρολογήστε ένα μήνυμα εδώ...";
out.contacts_info1 = "Αυτές είναι οι επαφές σας. Από εδώ, μπορείτε να:";
out.contacts_info2 = "Πατήσετε στο εικονίδιο της επαφής για να συνομιλήσετε μαζί τους";
out.contacts_info3 = "Κάνετε \"διπλό κλικ\" στο εικονίδιο για να δείτε το προφίλ τους";
out.contacts_info4 = "Ο κάθε συμμετέχων μπορεί να διαγράψει μόνιμα το ιστορικό μιας συνομιλίας";
out.contacts_removeHistoryTitle = 'Εκκαθάριση του ιστορικού συνομιλίας';
out.contacts_confirmRemoveHistory = 'Είστε σίγουροι πως θέλετε να διαγράψετε μόνιμα το ιστορικό; Τα δεδομένα δεν μπορούν να επαναφερθούν';
out.contacts_removeHistoryServerError = 'Προέκυψε ένα σφάλμα κατά της εκκαθάριση του ιστορικού. Δοκιμάστε ξανά αργότερα';
out.contacts_fetchHistory = "Ανάκτηση παλαιότερου ιστορικού";
// File manager
out.fm_rootName = "Έγγραφα";
out.fm_trashName = "Σκουπίδια";
out.fm_unsortedName = "Αταξινόμητα";
out.fm_filesDataName = "Όλα τα αρχεία";
out.fm_templateName = "Πρότυπα";
out.fm_searchName = "Αναζήτηση";
out.fm_recentPadsName = "Πρόσφατα pads";
out.fm_searchPlaceholder = "Αναζήτηση...";
out.fm_newButton = "Νέο";
out.fm_newButtonTitle = "Δημιουργήστε ένα νέο pad ή φάκελο, εισάγετε ένα αρχείο στον τρέχοντα φάκελο";
out.fm_newFolder = "Νέος φάκελος";
out.fm_newFile = "Νέο pad";
out.fm_folder = "Φάκελος";
out.fm_folderName = "Όνομα φακέλου";
out.fm_numberOfFolders = "# φακέλων";
out.fm_numberOfFiles = "# αρχείων";
out.fm_fileName = "Όνομα αρχείου";
out.fm_title = "Τίτλος";
out.fm_type = "Τύπος";
out.fm_lastAccess = "Τελευταία προσπέλαση";
out.fm_creation = "Δημιουργία";
out.fm_forbidden = "Απαγορευμένη ενέργεια";
out.fm_originalPath = "Πρωτότυπη διαδρομή";
out.fm_openParent = "Προβολή στον φάκελο";
out.fm_noname = "Έγγραφο χωρίς τίτλο";
out.fm_emptyTrashDialog = "Θέλετε σίγουρα να αδειάσετε τον κάδο;";
out.fm_removeSeveralPermanentlyDialog = "Θέλετε σίγουρα να αφαιρέσετε αυτά τα {0} αντικείμενα από το CryptDrive σας μόνιμα;";
out.fm_removePermanentlyDialog = "Θέλετε σίγουρα να αφαιρέσετε αυτό το αντικείμενο από το CryptDrive σας μόνιμα;";
out.fm_removeSeveralDialog = "Θέλετε σίγουρα να μετακινήσετε αυτά τα {0} αντικείμενα στον κάδο;";
out.fm_removeDialog = "Θέλετε σίγουρα να μετακινήσετε το {0} στον κάδο;";
out.fm_restoreDialog = "Θέλετε σίγουρα να επαναφέρετε το {0} στην προηγούμενη τοποθεσία του;";
out.fm_unknownFolderError = "Η επιλεγμένη ή πιο πρόσφατη τοποθεσία δεν υπάρχει πλέον. Γίνεται άνοιγμα του τρέχοντα φακέλου...";
out.fm_contextMenuError = "Αδυναμία ανοίγματος μενού για αυτό το αντικείμενο. Αν το πρόβλημα επιμείνει, δοκιμάστε να επαναφορτώσετε τη σελίδα.";
out.fm_selectError = "Αδυναμία επιλογής του συγκεκριμένου αντικειμένου. Αν το πρόβλημα επιμείνει, δοκιμάστε να επαναφορτώσετε τη σελίδα.";
out.fm_categoryError = "Αδυναμία ανοίγματος της επιλεγμένης κατηγορίας, γίνεται προβολή του γονικού φακέλου.";
out.fm_info_root = "Δημιουργήστε εδώ όσους υποφακέλους θέλετε για να ταξινομήσετε τα αρχεία σας.";
out.fm_info_unsorted = 'Περιέχει όλα τα αρχεία που έχετε επισκεφτεί αλλά δεν έχουν ταξινομηθεί στα "Έγγραφα", ούτε έχουν μετακινηθεί στα "Σκουπίδια".'; // "My Documents" should match with the "out.fm_rootName" key, and "Trash" with "out.fm_trashName"
out.fm_info_template = 'Περιέχει όλα τα pads που έχουν αποθηκευτεί ως πρότυπα και μπορείτε να ξαναχρησιμοποιήσετε όταν δημιουργείτε ένα νέο pad.';
out.fm_info_recent = "Λίστα των πρόσφατα τροποποιημένων ή ανοιγμένων pads.";
out.updated_0_fm_info_trash = 'Αδειάστε τον κάδο σας για να απελευθερώσετε χώρο στο CryptDrive σας.';
out.fm_info_trash = out.updated_0_fm_info_trash;
out.fm_info_allFiles = 'Περιέχει όλα τα αρχεία από τα "Έγγραφα", "Αταξινόμητα" και "Σκουπίδια". Δεν μπορείτε να μετακινήσετε ή να αφαιρέσετε αρχεία από εδώ.'; // Same here
out.fm_info_anonymous = 'Δεν έχετε συνδεθεί, οπότε τα pads σας θα διαγραφούν μετά από 3 μήνες (<a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">μάθετε περισσότερα</a>). ' +
'<a href="/register/">Εγγραφείτε</a> ή <a href="/login/">Συνδεθείτε</a> για να τα κρατήσετε επ\' αόριστον.';
out.fm_alert_backupUrl = "Σύνδεσμος ασφαλείας για αυτόν τον αποθηκευτικό χώρο.<br>" +
"Συνίσταται <strong>ιδιαιτέρως</strong> να τον κρατήσετε μυστικό.<br>" +
"Μπορείτε να τον χρησιμοποιήσετε για να ανακτήσετε όλα σας τα αρχεία σε περίπτωση που διαγραφεί η μνήμη του περιηγητή σας.<br>" +
"Οποιοσδήποτε με αυτόν τον σύνδεσμο μπορεί να επεξεργαστεί ή να αφαιρέσει όλα τα αρχεία σας στον διαχειριστή αρχείων.<br>";
out.fm_alert_anonymous = "Γεια σας! Αυτή τη στιγμή χρησιμοποιείτε το CryptPad ανώνυμα, αυτό είναι ok αλλά τα pads σας ίσως διαγραφούν μετά από ένα διάστημα " +
"αδράνειας. Έχουμε απενεργοποιήσει προηγμένες λειτουργίες του αποθηκευτικού χώρου για τους ανώνυμους χρήστες επειδή θέλουμε να καταστήσουμε ξεκάθαρο πως " +
'δεν είναι ένα ασφαλές μέρος για να αποθηκεύετε πράγματα. Μπορείτε να <a href="https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/" target="_blank">διαβάσετε περισσότερα</a> σχετικά ' +
'με το γιατί το κάνουμε αυτό και γιατί θα έπρεπε να <a href="/register/">Εγγραφείτε</a> ή να <a href="/login/">Συνδεθείτε</a>.';
out.fm_backup_title = 'Σύνδεσμος ασφαλείας';
out.fm_nameFile = 'Πως θα θέλατε να ονομάσετε αυτό το αρχείο;';
out.fm_error_cantPin = "Εσωτερικό σφάλμα διακομιστή. Παρακαλούμε επαναφορτώστε τη σελίδα και προσπαθήστε ξανά.";
out.fm_viewListButton = "Προβολή λίστας";
out.fm_viewGridButton = "Προβολή πλέγματος";
out.fm_renamedPad = "Έχετε ορίσει ένα προσαρμοσμένο όνομα για αυτό το pad. Ο διαμοιραζόμενος τίτλος του είναι:<br><b>{0}</b>";
out.fm_prop_tagsList = "Ετικέτες";
out.fm_burnThisDriveButton = "Διαγραφή όλων των πληροφοριών που έχουν αποθηκευτεί από το CryptPad στον περιηγητή σας";
out.fm_burnThisDrive = "Είστε σίγουροι πως θέλετε να διαγράψετε όλα όσα έχουν αποθηκευτεί από το CryptPad στον περιηγητή σας;<br>" +
"Αυτό θα αφαιρέσει το CryptDrive σας και το ιστορικό του από τον περιηγητή σας, αλλά τα pads σας θα εξακολουθήσουν να υπάρχουν (κρυπτογραφημένα) στον διακομιστή μας.";
// File - Context menu
out.fc_newfolder = "Νέος φάκελος";
out.fc_rename = "Μετονομασία";
out.fc_open = "Άνοιγμα";
out.fc_open_ro = "Άνοιγμα για προβολή μόνο";
out.fc_delete = "Μετακίνηση στον κάδο";
out.fc_restore = "Επαναφορά";
out.fc_remove = "Αφαίρεση από το CryptDrive σας";
out.fc_empty = "Άδειασμα του κάδου";
out.fc_prop = "Ιδιότητες";
out.fc_hashtag = "Ετικέτες";
out.fc_sizeInKilobytes = "Μέγεθος σε Kilobytes";
// fileObject.js (logs)
out.fo_moveUnsortedError = "Δεν μπορείτε να μετακινήσετε έναν φάκελο στη λίστα των αταξινόμητων pads";
out.fo_existingNameError = "Το όνομα χρησμοποιείται ήδη σε αυτή την τοποθεσία. Παρακαλώ επιλέξτε ένα άλλο.";
out.fo_moveFolderToChildError = "Δεν μπορείτε να μετακινήσετε έναν φάκελο μέσα σε κάποιο από τα περιεχόμενα του";
out.fo_unableToRestore = "Αδυναμία επαναφοράς αυτού του αρχείο στην αρχική τοποθεσία του. Μπορείτε να δοκιμάσετε να το μετακινήσετε σε μια νέα τοποθεσία.";
out.fo_unavailableName = "Ένα αρχείο ή ένας φάκελος με το ίδιο όνομα υπάρχει ήδη στη νέα τοποθεσία. Μετονομάστε το αρχείο και προσπαθήστε ξανά.";
out.fs_migration = "Το CryptDrive σας αναβαθμίστηκε σε μια νεότερη έκδοση. Ως αποτέλεσμα, η τρέχουσα σελίδα θα πρέπει να επαναφορτωθεί.<br><strong>Παρακαλούμε επαναφορτώστε τη σελίδα για να συνεχίσετε να την χρησιμοποιείτε.</strong>";
// login
out.login_login = "Σύνδεση";
out.login_makeAPad = 'Δημιουργήστε ένα pad ανώνυμα';
out.login_nologin = "Περιηγηθείτε στα τοπικά pads";
out.login_register = "Εγγραφή";
out.logoutButton = "Αποσύνδεση";
out.settingsButton = "Ρυθμίσεις";
out.login_username = "Όνομα χρήστη";
out.login_password = "Κωδικός";
out.login_confirm = "Επιβεβαίωση κωδικού";
out.login_remember = "Απομνημόνευση";
out.login_hashing = "Κρυπτογραφούμε τον κωδικό σας, αυτό μπορεί να πάρει λίγη ώρα.";
out.login_hello = 'Καλησπέρα {0},'; // {0} is the username
out.login_helloNoName = 'Καλησπέρα,';
out.login_accessDrive = 'Περιηγήθείτε στον αποθηκευτικό σας χώρο';
out.login_orNoLogin = 'ή';
out.login_noSuchUser = 'Μη έγκυρο όνομα χρήστη ή λάθος κωδικός. Προσπαθήστε ξανά, ή εγγραφείτε';
out.login_invalUser = 'Απαιτείται όνομα χρήστη';
out.login_invalPass = 'Απαιτείται κωδικός';
out.login_unhandledError = 'Προέκυψε ένα μη αναμενόμενο σφάλμα :(';
out.register_importRecent = "Εισαγωγή ιστορικού (Συνίσταται)";
out.register_acceptTerms = "Αποδέχομαι <a href='/terms.html' tabindex='-1'>τους όρους χρήσης</a> της υπηρεσίας";
out.register_passwordsDontMatch = "Οι κωδικοί δεν ταιριάζουν!";
out.register_passwordTooShort = "Οι κωδικοί πρέπει να αποτελούνται από τουλάχιστον {0} χαρακτήρες.";
out.register_mustAcceptTerms = "Πρέπει να αποδεχτείτε τους όρους της υπηρεσίας.";
out.register_mustRememberPass = "Δεν μπορούμε να επαναφέρουμε τον κωδικό σας αν τον ξεχάσετε. Είναι πολύ σημαντικό να τον θυμάστε! Παρακαλούμε πατήστε στο κουτάκι για επιβεβαίωση.";
out.register_header = "Καλώς ήρθατε στο CryptPad";
out.register_explanation = [
"<h3>Ας δούμε κάνα-δυο πράγματα πρώτα:</h3>",
"<ul class='list-unstyled'>",
"<li><i class='fa fa-info-circle'> </i> Ο κωδικός σας είναι το μυστικό κλειδί που κρυπτογραφεί όλα τα pads σας. Αν το χάσετε, δεν υπάρχει τρόπος να επαναφέρουμε τα δεδομένα σας.</li>",
"<li><i class='fa fa-info-circle'> </i> Μπορείτε να εισάγετε τα pads που ανοίξατε πρόσφατα στον περιηγητή σας ώστε να τα έχετε στον λογαριασμό σας.</li>",
"<li><i class='fa fa-info-circle'> </i> Αν χρησιμοποιείτε έναν κοινόχρηστο υπολογιστή, θα πρέπει να αποσυνδεθείτε όταν τελειώσετε, το να κλείσετε την καρτέλα δεν είναι αρκετό.</li>",
"</ul>"
].join('');
out.register_writtenPassword = "Έχω σημειώσει το όνομα χρήστη και τον κωδικό μου, συνέχεια";
out.register_cancel = "Επιστροφή";
out.register_warning = "Zero Knowledge σημαίνει πως δεν μπορούμε να επαναφέρουμε τον λογαριασμό σας αν χάσετε τον κωδικό σας.";
out.register_alreadyRegistered = "Αυτός ο χρήστης υπάρχει ήδη, μήπως θέλετε να συνδεθείτε;";
// Settings
out.settings_cat_account = "Λογαριασμός";
out.settings_cat_drive = "CryptDrive";
out.settings_cat_code = "Κώδικας";
out.settings_title = "Ρυθμίσεις";
out.settings_save = "Αποθήκευση";
out.settings_backupCategory = "Αντίγραφο ασφαλείας";
out.settings_backupTitle = "Αποθηκεύστε ή επαναφέρετε όλα σας τα δεδομένα";
out.settings_backup = "Δημιουργία αντιγράφου ασφαλείας";
out.settings_restore = "Επαναφορά από αντίγραφο ασφαλείας";
out.settings_resetNewTitle = "Εκκαθάριση του CryptDrive";
out.settings_resetButton = "Αφαίρεση";
out.settings_reset = "Αφαίρεση όλων των αρχείων και φακέλων από το CryptDrive σας";
out.settings_resetPrompt = "Αυτή η ενέργεια θα αφαιρέσει όλα τα pads από τον αποθηκευτικό σας χώρο.<br>"+
"Θέλετε σίγουρα να συνεχίσετε;<br>" +
"Πληκτρολογήστε “<em>I love CryptPad</em>” για επιβεβαίωση.";
out.settings_resetDone = "Ο αποθηκευτικός σας χώρος είναι πλέον άδειος!";
out.settings_resetError = "Λάθος κείμενο επιβεβαίωσης. Το CryptDrive σας δεν έχει αλλαχθεί.";
out.settings_resetTipsAction = "Επαναφορά";
out.settings_resetTips = "Συμβουλές";
out.settings_resetTipsButton = "Επαναφέρετε όλες τις διαθέσιμες συμβουλές για το CryptDrive";
out.settings_resetTipsDone = "Όλες οι συμβουλές είναι πάλι ορατές.";
out.settings_thumbnails = "Μικρογραφίες";
out.settings_disableThumbnailsAction = "Απενεργοποίηση μικρογραφιών στο CryptDrive σας";
out.settings_disableThumbnailsDescription = "Οι μικρογραφίες δημιουργούνται αυτόματα και αποθηκεύονται στον περιηγητή σας όταν επισκέπτεστε ένα νέο pad. Μπορείτε να απενεργοποιήσετε αυτό το χαρακτηριστικό εδώ.";
out.settings_resetThumbnailsAction = "Εκκαθάριση";
out.settings_resetThumbnailsDescription = "Εκκαθάριση όλων των μικρογραφιών που έχουν αποθηκευτεί στον περιηγητή σας.";
out.settings_resetThumbnailsDone = "Όλες οι μικρογραφίες έχουν διαγραφεί.";
out.settings_importTitle = "Εισάγετε τα πρόσφατα pads αυτού του περιηγητή στο CryptDrive σας";
out.settings_import = "Εισαγωγή";
out.settings_importConfirm = "Είσαστε σίγουρος ότι θέλετε να εισάγετε τα πρόσφατα pads από αυτόν τον περιηγητή στον λογαριασμό χρήστη σας στο CryptDrive?";
out.settings_importDone = "Εισαγωγή ολοκληρώθηκε";
out.settings_userFeedbackTitle = "Αναπληροφόρηση";
out.settings_userFeedbackHint1 = "Το CryptPad αποστέλλει κάποιες πολύ βασικές πληροφορίες σ' εμάς, ώστε να μας ενημερώσει για το πως μπορούμε να βελτιώσουμε την εμπειρία σας.";
out.settings_userFeedbackHint2 = "Το περιεχόμενο των pads σας δεν διαμοιράζεται ποτέ μαζί μας.";
out.settings_userFeedback = "Ενεργοποίηση αναπληροφόρησης χρήστη";
out.settings_anonymous = "Δεν είσαστε συνδεδεμένος. Οι τρέχουσες ρυθμίσεις ισχύουν μόνο για τον συγκεκριμένο περιηγητή.";
out.settings_publicSigningKey = "Δημόσιο κλειδί κρυπτογράφησης";
out.settings_usage = "Χρήση";
out.settings_usageTitle = "Δείτε ολόκληρο το μέγεθος των καρφιτσωμένων pads σας σε MB";
out.settings_pinningNotAvailable = "Τα καρφιτσωμένα pads είναι διαθέσιμα μόνο σε εγγεγραμένους χρήστες.";
out.settings_pinningError = "Κάτι πήγε στραβά";
out.settings_usageAmount = "Τα καρφιτσωμένα pads σας καταναλώνουν σε χώρο {0}MB";
out.settings_logoutEverywhereButton = "Αποσύνδεση";
out.settings_logoutEverywhereTitle = "Αποσύνδεση παντού";
out.settings_logoutEverywhere = "Εξαναγκασμός αποσύνδεσης όλων των άλλων διαδικτυακών συνεδριών.";
out.settings_logoutEverywhereConfirm = "Είσαστε σίγουροι; Θα χρειαστεί να επανασυνδεθείτε σε όλες σας τις συσκευές.";
out.settings_codeIndentation = 'Εσοχές στον επεξεργαστή κώδικα (κενά)';
out.settings_codeUseTabs = "Εισαγωγή εσoχών με χρήση του πλήκτρου tab, αντί κενών";
out.upload_title = "Μεταφόρτωση αρχείου";
out.upload_rename = "Θέλετε να μετονομάσετε το <b>{0}</b> πριν το μεταφορτώσετε στον διακομιστή;<br>" +
"<em>Η κατάληξη του αρχείου ({1}) θα προστεθεί αυτόματα. "+
"Αυτό το όνομα θα είναι μόνιμο και ορατό σε άλλους χρήστες.</em>";
out.upload_serverError = "Λάθος Διακομιστή: δεν μπορούμε να μεταφορτώσουμε το αρχείο σας αυτή την στιγμή.";
out.upload_uploadPending = "Προσπαθείτε ήδη να μεταφορτώσετε κάτι αυτή την στιγμή. Ακύρωση και μεταφόρτωση του κανούριου σας αρχείου;";
out.upload_success = "Το αρχείο σας ({0}) έχει μεταφορτωθεί επιτυχώς κι έχει προστεθεί στον αποθηκευτικό σας χώρο.";
out.upload_notEnoughSpace = "Δεν υπάρχει αρκετός αποθηκευτικός χώρος γι' αυτό το αρχείο στο CryptDrive σας.";
out.upload_tooLarge = "Αυτό το αρχείο ξεπερνάει το μέγιστο μέγεθος μεταφόρτωσης.";
out.upload_choose = "Επιλέξτε ένα αρχείο";
out.upload_pending = "Εκρεμμεί";
out.upload_cancelled = "Ακυρώθηκε";
out.upload_name = "Όνομα αρχείου";
out.upload_size = "Μέγεθος";
out.upload_progress = "Εξέλιξη";
out.upload_mustLogin = "Πρέπει να είσαστε συνδεδεμένος για να μεταφορτώσετε ένα αρχείο";
out.download_button = " Αποκρυπτογράφηση & Κατέβασμα";
out.download_mt_button = "Λήψη";
out.todo_title = "CryptTodo";
out.todo_newTodoNamePlaceholder = "Περιγράψτε την εργασία σας...";
out.todo_newTodoNameTitle = "Προσθέστε την εργασία σας στη λίστα εργασιών";
out.todo_markAsCompleteTitle = "Σημειώστε αυτή την εργασία ως ολοκληρωμένη";
out.todo_markAsIncompleteTitle = "Σημειώστε αυτή την εργασία ως ανολοκλήρωτη";
out.todo_removeTaskTitle = "Αφαιρέστε αυτή την εργασία από την λίστα εργασιών σας";
// pad
out.pad_showToolbar = "Εμφάνιση γραμμής εργαλείων";
out.pad_hideToolbar = "Απόκρυψη γραμμής εργαλείων";
// general warnings
out.warn_notPinned = "Αυτό το pad δεν είναι αποθηκευμένο σε κάποιο CryptDrive. Θα διαγραφεί σε 3 μήνες. <a href='/about.html#pinning'>Μάθετε περισσότερα...</a>";
// markdown toolbar
out.mdToolbar_button = "Εμφάνιση ή απόκρυψη της γραμμής εργαλείων Markdown";
out.mdToolbar_defaultText = "Το κείμενο σας εδώ";
out.mdToolbar_help = "Βοήθεια";
out.mdToolbar_tutorial = "http://www.markdowntutorial.com/";
out.mdToolbar_bold = "Έντονα";
out.mdToolbar_italic = "Πλάγια";
out.mdToolbar_strikethrough = "Διεγραμμένα";
out.mdToolbar_heading = "Επικεφαλίδα";
out.mdToolbar_link = "Σύνδεσμος";
out.mdToolbar_quote = "Παράθεση";
out.mdToolbar_nlist = "Λίστα με αριθμούς";
out.mdToolbar_list = "Λίστα με σημεία";
out.mdToolbar_check = "Λίστα εργασιών";
out.mdToolbar_code = "Κώδικας";
// index.html
//about.html
out.main_p2 = 'Αυτό το εγχείρημα χρησιμοποιεί τον γραφικό επεξεργαστή <a href="http://ckeditor.com/">CKEditor</a>, <a href="https://codemirror.net/">CodeMirror</a>, και την μηχανή πραγματικού χρόνου <a href="https://github.com/xwiki-contrib/chainpad">ChainPad</a>.';
out.main_howitworks_p1 = 'Το CryptPad χρησιμοποιεί μια παραλλαγή του αλγόριθμου <a href="https://en.wikipedia.org/wiki/Operational_transformation">Operational transformation</a> με τον οποίο καταφέρνει να πετύχει κατανεμημένη συναίνεση χρησιμοποιώντας <a href="https://bitcoin.org/bitcoin.pdf">Blockchain</a>, μια δομή που έγινε δημοφιλής μέσω του <a href="https://en.wikipedia.org/wiki/Bitcoin">Bitcoin</a>. Με αυτό τον τρόπο ο αλγόριθμος αποφεύγει την ανάγκη ύπαρξης ενός κεντρικού διακομιστή για να επιλύσει συγκρούσεις ταυτόχρονης επεξεργασίας και χωρίς την ανάγκη επίλυσης αυτών των συγκρούσεων, ο διακομιστής δεν χρειάζεται να έχει γνώση του περιεχομένου που υπάρχει στο pad.';
// contact.html
out.main_about_p2 = 'Αν έχετε απορίες ή σχόλια, επικοινωνήστε μαζί μας!<br/>Μπορείτε να στείλετε <a href="https://twitter.com/cryptpad"><i class="fa fa-twitter"></i>ένα tweet</a>, να δημιουργήσετε ένα θέμα <a href="https://github.com/xwiki-labs/cryptpad/issues/" title="our issue tracker">στο <i class="fa fa-github"></i>GitHub</a>. Ελάτε να πείτε "γεια" <a href="https://riot.im/app/#/room/#cryptpad:matrix.org" title="Matrix">στο <i class="fa fa-comment"></i>Matrix κανάλι μας</a> ή στο IRC (#cryptpad on irc.freenode.net), ή <a href="mailto:research@xwiki.com"><i class="fa fa-envelope"></i>στείλτε μας ένα email</a>.';
out.main_about_p22 = 'Στείλτε μας ένα tweet';
out.main_about_p23 = 'Δημιουργήστε ένα θέμα στο GitHub';
out.main_about_p24 = 'Πείτε "γεια" στο Matrix';
out.main_about_p25 = 'Στείλτε μας ένα email';
out.main_about_p26 = 'Αν έχετε απορίες ή σχόλια, επικοινωνήστε μαζί μας!';
out.main_info = "<h2>Συνεργαστείτε με ασφάλεια</h2> Αναπτύξτε τις ιδέες σας μαζί με κοινά αρχεία όσο η τεχνολογία <strong>Zero Knowledge</strong> εξασφαλίζει την ιδιωτικότητά σας; <strong>ακόμη κι από εμάς</strong>.";
out.main_catch_phrase = "Το Zero Knowledge σύννεφο";
out.main_howitworks = 'Πως Λειτουργεί';
out.main_zeroKnowledge = 'Πρωτόκολλο Zero Knowledge';
out.main_zeroKnowledge_p = "Δεν χρειάζεται να μας εμπιστευθείτε όταν σας λέμε πως <em>δεν θα κοιτάξουμε</em> τα pads σας, διότι με την επαναστατική τεχνολογία Zero Knowledge του CryptPad <em>δεν μπορούμε</em> να τα κοιτάξουμε. Μάθετε περισσότερα για το πως προστατεύουμε την <a href=\"/privacy.html\" title='Privacy'>Ασφάλεια και Ιδιωτικότητά</a> σας.";
out.main_writeItDown = 'Σημειώστε το';
out.main_writeItDown_p = "Τα μεγαλύτερα έργα προέρχονται από τις μικρότερες ιδέες. Καταγράψτε τις στιγμές έμπνευσης και τις απροσδόκητες ιδέες σας διότι ποτέ δεν ξέρετε ποια από αυτές μπορεί να είναι η επόμενη μεγάλη ανακάλυψη.";
out.main_share = 'Μοιραστείτε τον σύνδεσμο, μοιραστείτε το pad';
out.main_share_p = "Αναπτύξτε τις ιδέες σας μαζί: πραγματοποιήστε αποτελεσματικές συναντήσεις, συνεργαστείτε στις λίστες εργασιών και κάντε γρήγορες παρουσιάσεις με όλους τους φίλους σας και από όλες τις συσκευές σας.";
out.main_organize = 'Οργανωθείτε';
out.main_organize_p = "Με το CryptPad Drive, μπορείτε να συγκεντρωθείτε στο τι είναι σημαντικό. Οι φάκελοι σας επιτρέπουν να ελέγχετε τα έργα σας και να έχετε μία συνολική εικόνα για το πως προχωράνε τα πράγματα.";
out.tryIt = 'Δοκιμάστε το!';
out.main_richText = 'Επεξεργαστής Εμπλουτισμένου Κειμένου';
out.main_richText_p = 'Επεξεργαστείτε pads εμπλουτισμένου κειμένου συνεργατικά με την πραγματικού χρόνου Zero Knowledge εφαρμογή μας <a href="http://ckeditor.com" target="_blank">CkEditor</a>.';
out.main_code = 'Επεξεργαστής κώδικα';
out.main_code_p = 'Επεξεργαστείτε κώδικα συνεργατικά με την πραγματικού χρόνου Zero Knowledge εφαρμογή μας <a href="https://www.codemirror.net" target="_blank">CodeMirror</a>.';
out.main_slide = 'Επεξεργαστής Slide';
out.main_slide_p = 'Δημιουργείστε τις παρουσιάσεις σας χρησιμοποιώντας μορφοποίηση Markdown και προβάλλετέ τις στον περιηγητή σας.';
out.main_poll = 'Δημοσκοπήσεις';
out.main_poll_p = 'Προγραμματίστε την συνάντησή σας ή την δραστηριότητά σας, ή ψηφίστε την καλύτερη λύση σχετικά με το πρόβλημά σας.';
out.main_drive = 'CryptDrive';
out.main_richTextPad = 'Pad εμπλουτισμένου κειμένου';
out.main_codePad = 'Pad κώδικα';
out.main_slidePad = 'Markdown παρουσίαση';
out.main_pollPad = 'Δημοσκόπηση ή Χρονοδιάγραμμα';
out.main_whiteboardPad = 'Πίνακας σχεδιασμού';
out.main_localPads = 'Τοπικά pads';
out.main_yourCryptDrive = 'Το CryptDrive σας';
out.main_footerText = "Με το CryptPad, μπορείτε να δημιουργήσετε γρήγορα συνεργατικά έγγραφα για κοινόχρηστες σημειώσεις και καταγραφή ιδεών.";
out.footer_applications = "Εφαρμογές";
out.footer_contact = "Επικοινωνία";
out.footer_aboutUs = "Σχετικά με εμάς";
out.about = "Σχετικά";
out.privacy = "Ιδιωτικότητα";
out.contact = "Επικοινωνία";
out.terms = "Όροι χρήσης";
out.blog = "Ιστολόγιο";
out.topbar_whatIsCryptpad = "Τι είναι το CryptPad";
// what-is-cryptpad.html
out.whatis_title = 'Τι είναι το CryptPad';
out.whatis_collaboration = 'Γρήγορη, εύκολη συνεργασία';
out.whatis_collaboration_p1 = 'Με το CryptPad, μπορείτε να δημιουργείτε όλοι μαζί γρήγορα συνεργατικά έγγραφα για τις σημειώσεις σας και τις ιδέες που καταγράφετε. Όταν εγγραφείτε και συνδεθείτε, σας δίνεται άμεσα η δυνατότητα \'ανεβάσματος\' κι έναν \'αποθηκευτικό χώρο\' CryptDrive όπου μπορείτε να οργανώσετε όλα σας τα pads. Ως εγγεγραμένος χρήστης παίρνετε 50MB δωρεάν.';
out.whatis_collaboration_p2 = 'Μπορείτε να μοιραστείτε την πρόσβαση σε ένα έγγραφο του CryptPad απλά δίνοντας τον σύνδεσμο σε κάποιον άλλο. Μπορείτε επίσης να μοιραστείτε ένα σύνδεσμο ο οποίος παρέχει πρόσβαση <em>μόνο για ανάγνωση</em> σε ένα pad, επιτρέποντάς σας να κοινοποιήσετε την συλλογική σας δουλειά ενώ ταυτόχρονα έχετε ακόμα τη δυνατότητα να το επεξεργαστείτε.';
out.whatis_collaboration_p3 = 'Μπορείτε να δημιουργήσετε απλά εμπλουτισμένα κείμενα με το <a href="http://ckeditor.com/">CKEditor</a> όπως επίσης κείμενα με γλώσσα προγραμματισμού Markdown τα οποία τροποποιούνται σε πραγματικό χρόνο καθώς πληκτρολογείτε. Μπορείτε επίσης να χρησιμοποιήσετε την εφαρμογή δημοσκόπησης για να προγραμματίσετε δραστηριότητες με πολλαπλούς συμμετέχοντες.';
out.whatis_zeroknowledge = 'Zero Knowledge';
out.whatis_zeroknowledge_p1 = "Δεν θέλουμε να ξέρουμε τι πληκτρολογείτε και με τον σύγχρονο τρόπο κρυπτογράφησης μπορείτε να είσαστε σίγουροι ότι δεν μπορούμε να ξέρουμε. Το CryptPad χρησιμοποιεί <strong>100% κρυπτογράφηση client side</strong> για να προστατεύσει το περιεχόμενο που πληκτρολογείτε από εμάς, τους ανθρώπους που φιλοξενούν τον διακομιστή.";
out.whatis_zeroknowledge_p2 = 'Όταν κάνετε εγγραφή και συνδέεστε, το όνομα χρήστη σας κι ο κωδικός σας μετατρέπονται σε ένα κρυπτογραφημένο κλειδί χρησιμοποιώντας το <a href="https://en.wikipedia.org/wiki/Scrypt">scrypt key derivation function</a>. Το συγκεκριμένο κλειδί, το όνομα χρήστη κι ο κωδικός χρήστη δεν στέλνονται καν στον διακομιστή. Αντιθέτως χρησιμοποιούνται από το client side για να αποκρυπτογραφήσουν το περιεχόμενο του CryptDrive σας, το οποίο περιέχει όλα τα κλειδιά για όλα τα pads στα οποία μπορείτε να έχετε πρόσβαση.';
out.whatis_zeroknowledge_p3 = 'Όταν μοιράζεστε έναν σύνδεσμο προς ένα έγγραφο, μοιράζεστε το κρυπτογραφημένο κλειδί για το συγκεκριμένο έγγραφο αλλά εφόσον το κλειδί είναι στο <a href="https://en.wikipedia.org/wiki/Fragment_identifier">fragment identifier</a>, δεν στέλνεται ποτέ απευθείας στον διακομιστή. Επισκεφθείτε το <a href="https://blog.cryptpad.fr/2017/07/07/cryptpad-analytics-what-we-cant-know-what-we-must-know-what-we-want-to-know/">privacy blog post</a> για να μάθετε περισσότερα σχετικά με το σε ποια μεταδεδομένα έχουμε πρόσβαση και σε ποια όχι.';
out.whatis_drive = 'Οργάνωση με το CryptDrive';
out.whatis_drive_p1 = 'Κάθε φορά που επισκέπτεσθε ένα pad στο CryptPad, το pad προστίθεται αυτόματα στο CryptDrive στον κυρίως φάκελο. Αργότερα μπορείτε να οργανώσετε αυτά τα pad σε φακέλους ή μπορείτε να τα μετακινήσετε στον κάδο ανακύκλωσης. Το CryptDrive σας επιτρέπει να περιηγηθείτε ανάμεσα στα pads σας και να τα οργανώνετε όποτε κι όπως θέλετε.';
out.whatis_drive_p2 = 'Με το κλασικό drag-and-drop, μπορείτε να μεταφέρετε pads μέσα στον αποθηκευτικό σας χώρο και ο σύνδεσμος αυτών των pads θα παραμείνει ο ίδιος ώστε οι συνεργάτες σας να μην σταματήσουν ποτέ να έχουν πρόσβαση.';
out.whatis_drive_p3 = 'Μπορείτε επίσης να ανεβάσετε αρχεία στο CryptDrive σας και να τα μοιραστείτε με συνεργάτες. Τα ανεβασμένα αρχεία μπορούν να οργανωθούν ακριβώς όπως τα συνεργατικά pads.';
out.whatis_business = 'Το CryptPad για επιχειρήσεις';
out.whatis_business_p1 = 'Το πρωτόκολλο κρυπτογράφησης Zero Knowledge του CryptPad είναι ιδανικό για να πολλαπλασιαστεί η αποτελεσματικότητα των ήδη υπάρχοντων πρωτοκόλλων ασφαλείας προστατεύοντας τα εταιρικά στοιχεία πρόσβασης με ισχυρή κρυπτογράφηση. Επειδή τα ευαίσθητα δεδομένα μπορούν να αποκρυπτογραφηθούν μόνο με την χρήση των στοιχείων των υπαλλήλων, το CryptPad εξαλείφει τον παράγοντα hacker ο οποίος ενυπάρχει σε παραδοσιακούς εταιρικούς διακομιστές. Διαβάστε το <a href="https://blog.cryptpad.fr/images/CryptPad-Whitepaper-v1.0.pdf">CryptPad Whitepaper</a> για να μάθετε περισσότερα σχετικά με το πως μπορεί να βοηθήσει την επιχείρησή σας.';
out.whatis_business_p2 = 'To CryptPad μπορεί να εγκατασταθεί τοπικά και οι <a href="https://cryptpad.fr/about.html">προγραμματιστές του</a> στην XWiki SAS είναι σε θέση να προσφέρουν εμπορική υποστήριξη, τροποποιήσεις και περαιτέρω ανάπτυξη. Επικοινωνήστε στο <a href="mailto:sales@cryptpad.fr">sales@cryptpad.fr</a> για περισσότερες πληροφορίες.';
// privacy.html
out.policy_title = 'Πολιτική απορρήτου του CryptPad';
out.policy_whatweknow = 'Τι γνωρίζουμε για εσάς';
out.policy_whatweknow_p1 = 'Ως εφαρμογή η οποία φιλοξενείται στο διαδίκτυο, το CryptPad έχει πρόσβαση στα μεταδεδομένα που είναι εκτεθειμένα από το πρωτόκολλο HTTP. Αυτό συμπεριλαμβάνει την διεύθυνση IP σας και ποικίλες HTTP κεφαλίδες που μπορούν να χρησιμοποιηθούν για να ταυτοποιήσουν τον συγκεκριμένο περιηγητή. Μπορείτε να δείτε τι πληροφορίες μοιράζεται ο περιηγητής σας με το να επισκεφθείτε <a target="_blank" rel="noopener noreferrer" href="https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending" title="what http headers is my browser sending">WhatIsMyBrowser.com</a>.';
out.policy_whatweknow_p2 = 'Χρησιμοποιούμε το <a href="https://www.elastic.co/products/kibana" target="_blank" rel="noopener noreferrer" title="open source analytics platform">Kibana</a>, μια πλατφόρμα ανάλυσης ανοιχτού κώδικα, για να μάθουμε περισσότερα για τους χρήστες μας. Το Κibana μας ενημερώνει για το πως βρήκατε το CryptPad, μέσω απευθείας σύνδεσης, μέσω μηχανής αναζήτησης, ή μέσω αναφοράς από άλλη διαδυκτιακή υπηρεσία όπως το Reddit ή το Twitter.';
out.policy_howweuse = 'Πώς χρησιμοποιούμε αυτά που μαθαίνουμε';
out.policy_howweuse_p1 = 'Χρησιμοποιούμε αυτές τις πληροφορίες για να παίρνουμε καλύτερες αποφάσεις σχετικά με την προώθηση του CryptPad, εξετάζοντας ποιες από τις προηγούμενες προσπάθειές μας υπήρξαν επιτυχείς. Οι πληροφορίες σχετικά με την τοποθεσία σας μας βοηθούν στο να σκεφτούμε αν θα έπρεπε να παρέχουμε καλύτερη υποστήριξη για γλώσσες εκτός των Αγγλικών.';
out.policy_howweuse_p2 = "Οι πληροφορίες σχετικά με τον περιηγητή σας (είτε είναι επιτραπέζιου είτε φορητού λειτουργικού συστήματος) μας βοηθάνε να παίρνουμε αποφάσεις στο θέμα προτεραιοτήτων βελτίωσης χαρακτηριστικών. Η ομάδα προγραμματισμού μας είναι μικρή και προσπαθούμε να κάνουμε επιλογές οι οποίες θα βελτιώσουν την εμπειρία όσων το δυνατό περισσότερων χρηστών.";
out.policy_whatwetell = 'Τι λέμε σε άλλους για εσάς';
out.policy_whatwetell_p1 = 'Δεν παρέχουμε σε τρίτους τις πληροφορίες που συλλέγουμε ή τις πληροφορίες που μας δίνετε εκτός κι αν είμαστε υποχρεωμένοι νομικά.';
out.policy_links = 'Σύνδεσμοι σε άλλες σελίδες';
out.policy_links_p1 = 'Αυτή η ιστοσελίδα περιέχει συνδέσμους προς άλλες σελίδες, συμπεριλαμβανομένων αυτών που δημιουργήθηκαν από άλλους οργανισμούς. Δεν είμαστε υπεύθυνοι για την πολιτική απορρήτου ή το περιεχόμενο μιας εξωτερικής σελίδας. Ως γενικό κανόνα έχουμε πως οι σύνδεσμοι σε διαφορετικές σελίδες ανοίγουν σε καινούριο παράθυρο για να είναι ξεκάθαρο ότι φεύγετε από το CryptPad.fr.';
out.policy_ads_p1 = 'Δεν προβάλουμε διαφημίσεις εντός της υπηρεσίας, όμως μπορεί να παρέχουμε συνδέσμους στους ανθρώπους που ενισχύουν οικονομικά την έρευνά μας.';
out.policy_choices = 'Οι επιλογές που έχετε';
out.policy_choices_open = 'Ο κώδικάς μας διατίθεται ελεύθερα, οπότε έχετε πάντα την επιλογή να φιλοξενήσετε το Cryptpad σε δικό σας διακομιστή.';
out.policy_choices_vpn = 'Εάν θέλετε να χρησιμοποιήσετε τη δική μας εκδοχή του Cryptpad, αλλά δεν θέλετε να φαίνεται η IP διεύθυνσή σας, μπορείτε να προστατέψετε την IP σας χρησιμοποιώντας το <a href="https://www.torproject.org/projects/torbrowser.html.en" title="downloads from the Tor project" target="_blank" rel="noopener noreferrer">Tor browser bundle</a>, ή ένα <a href="https://riseup.net/en/vpn" title="VPNs provided by Riseup" target="_blank" rel="noopener noreferrer">VPN</a>.';
out.policy_choices_ads = 'Εάν θα θέλατε απλά να εμποδίσετε την πλατφόρμα ανάλυσής μας, μπορείτε να χρησιμοποιήσετε εργαλεία απόκρυψης διαφημίσεων όπως το <a href="https://www.eff.org/privacybadger" title="download privacy badger" target="_blank" rel="noopener noreferrer">Privacy Badger</a>.';
// terms.html
out.tos_title = " Όροι και Προϋποθέσεις του CryptPad";
out.tos_legal = "Παρακαλούμε μην κάνετε κακή χρήση ή/και κατάχρηση της υπηρεσίας ή οτιδήποτε παράνομο.";
out.tos_availability = "Ελπίζουμε να βρείτε χρήσιμη αυτή την υπηρεσία, αλλά η προσβασιμότητα κι η απόδοση δεν μπορούν να εγγυηθούν. Παρακαλούμε κάνετε εξαγωγή των δεδομένων σας συχνά.";
out.tos_e2ee = "Τα περιεχόμενα του CryptPad μπορούν να διαβαστούν ή να αλλαχθούν από οποιονδήποτε μπορεί να μαντέψει ή να αποκτήσει την ηλεκτρονική διεύθυνση του pad. Προτείνουμε να χρησιμοποιείτε τεχνολογία κρυπτογραφημένων μηνυμάτων από άκρη σε άκρη (e2ee) για να μοιράζεστε συνδέσμους και να μην αναλάβετε καμία ευθύνη σε περίπτωση που διαρρέυσει κάποιος τέτοιος σύνδεσμος.";
out.tos_logs = "Τα μεταδεδομένα που παρέχονται από τον περιηγητή σας στον διακομιστή μπορεί να καταγράφονται με σκοπό τη συντήρηση της υπηρεσίας.";
out.tos_3rdparties = "Δεν παρέχουμε προσωπικά δεδομένα σε τρίτους παρά μόνο εάν ζητηθεί από το νόμο.";
// 404 page
out.four04_pageNotFound = "Η σελίδα που ψάχνετε, δεν βρέθηκε!";
// BottomBar.html
//out.bottom_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Δημιουργήθηκε με <img class="bottom-bar-heart" src="/customize/heart.png" alt="love" /> στην <img class="bottom-bar-fr" src="/customize/fr.png" alt="Γαλλία" /></a>';
//out.bottom_support = '<a href="http://labs.xwiki.com/" title="XWiki Labs" target="_blank" rel="noopener noreferrer">Ένα <img src="/customize/logo-xwiki2.png" alt="XWiki SAS" class="bottom-bar-xwiki"/> Labs Project </a> με την υποστήριξη του <a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
// Header.html
out.header_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Με <img class="bottom-bar-heart" src="/customize/heart.png" alt="love" /> στην <img class="bottom-bar-fr" src="/customize/fr.png" title="Γαλλία" alt="Γαλλία"/> από την <img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
out.header_support = '<a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
out.updated_0_header_logoTitle = 'Μετάβαση στο CryptDrive σας';
out.header_logoTitle = out.updated_0_header_logoTitle;
out.header_homeTitle = 'Μετάβαση στην αρχική σελίδα του CryptPad';
// Initial states
out.initialState = [
'<p>',
'Αυτό είναι&nbsp;<strong>CryptPad</strong>, ο συνεργατικός επεξεργαστής πραγματικού χρόνου Zero Knowledge. Τα πάντα αποθηκεύονται καθώς πληκτρολογείτε.',
'<br>',
'Μοιραστείτε τον σύνδεσμο σε αυτό το pad για να το επεξεργαστείτε με φίλους ή χρησιμοποιήστε το κουμπί <span class="fa fa-share-alt"></span> για να μοιραστείτε ένα κείμενο με δικαιώματα <em>read-only link</em>&nbsp;το οποίο επιτρέπει να το αναγνώσει κάποιος αλλά όχι να το επεξεργαστεί.',
'</p>',
].join('');
out.codeInitialState = [
'# Ο συνεργατικός επεξεργαστής Zero Knowledge του CryptPad\n',
'\n',
'* Ό,τι πληκτρολογείτε εδώ είναι κρυπτογραφημένο έτσι ώστε μόνο οι άνθρωποι που έχουν τον σύνδεσμο να μπορούν να έχουν πρόσβαση.\n',
'* Μπορείτε να επιλέξετε την γλώσσα προγραμματισμού για να υπογραμμίζετε και το χρώμα του θέματος UI πάνω δεξιά.'
].join('');
out.slideInitialState = [
'# CryptSlide\n',
'1. Γράψτε τα περιεχόμενα των slides σας χρησιμοποιώντας σύνταξη markdown\n',
' - Μάθετε περισσότερα για την σύνταξη markdown [εδώ](http://www.markdowntutorial.com/)\n',
'2. Διαχωρίστε τα slides σας με ---\n',
'3. Πατήστε το κουμπάκι "Play" για να δείτε το αποτέλεσμα',
' - Τα slides σας ενημερώνονται σε πραγματικό χρόνο'
].join('');
// Readme
out.driveReadmeTitle = "Τι είναι το CryptPad;";
out.readme_welcome = "Καλωσήρθατε στο CryptPad!";
out.readme_p1 = "Καλωσήρθατε στο CryptPad, όπου μπορείτε να έχετε τις σημειώσεις σας μόνοι σας ή με φίλους.";
out.readme_p2 = "Αυτό το pad έχει έναν γρήγορο οδηγό χρήσης του πως να χρησιμοποιήσετε το CryptPad για να κρατάτε σημειώσεις, να τις έχετε οργανωμένες και να δουλέψετε πάνω τους συνεργατικά.";
out.readme_cat1 = "Μάθετε το CryptDrive σας";
out.readme_cat1_l1 = "Δημιούργηστε ένα pad: Στο CryptDrive σας, κάντε \"κλικ\" στο {0} και έπειτα στο {1} και μπορείτε να δημιουργήσετε ένα pad."; // 0: New, 1: Rich Text
out.readme_cat1_l2 = "Ανοίξτε pads από το CryptDrive σας: κάντε διπλό \"κλικ\" σε ένα εικονίδιο pad για να το ανοίξετε.";
out.readme_cat1_l3 = "Οργάνωστε τα pads σας: Όταν είσαστε συνδεδεμένοι, κάθε pad στο οποίο έχετε πρόσβαση θα εμφανίζεται ως {0} στο τμήμα του δίσκου σας."; // 0: Unsorted files
out.readme_cat1_l3_l1 = "Μπορείτε να κάνετε \"κλικ\" και να σύρετε αρχεία μέσα σε φακέλους στον τομέα {0} του δίσκου σας και να δημιουργήσετε καινούρια αρχεία."; // 0: Documents
out.readme_cat1_l3_l2 = "Θυμηθείτε να δοκιμάζετε το δεξί \"κλικ\" στα εικονίδια διότι συχνά υπάρχουν επιπρόσθετα μενού.";
out.readme_cat1_l4 = "Πετάξτε τα παλιά pads στα σκουπίδια: Μπορείτε να κάνετε \"κλικ\" και να σύρετε τα pads μέσα στα {0} με τον ίδιο τρόπο που τα σύρετε μέσα στους φακέλους."; // 0: Trash
out.readme_cat2 = "Δημιουργείστε pads σαν επαγγελματίας";
out.edit = "επεξεργασία";
out.view = "προβολή";
out.readme_cat2_l1 = "Το κουμπί {0} στο pad σας επιτρέπει να δίνετε πρόσβαση στους συνεργάτες σας είτε να κάνουν {1} είτε να κάνουν {2} το pad."; // 0: Share, 1: edit, 2: view
out.readme_cat2_l2 = "Αλλάξτε τον τίτλο του pad κάνοντας \"κλικ\" στο μολύβι";
out.readme_cat3 = "Ανακαλύψτε CryptPad εφαρμογές";
out.readme_cat3_l1 = "Με το CryptPad code editor, μπορείτε να συνεργαστείτε σε κώδικα όπως οι γλώσσες προγραμματισμού Javascript και markdown ή HTML και Markdown";
out.readme_cat3_l2 = "Με το CryptPad slide editor, μπορείτε να κάνετε γρήγορες παρουσιάσεις χρησιμοποιώντας γλώσσα Markdown";
out.readme_cat3_l3 = "Με το CryptPoll μπορείτε να ψηφίζετε γρήγορα, ειδικά για να ορίζετε συναντήσεις σε ημερομηνίες που ταιριάζουν με το πρόγραμμα όλων";
// Tips
out.tips = {};
out.tips.shortcuts = "`ctrl+b`, `ctrl+i` και `ctrl+u` είναι γρήγορες συντομεύσεις για έντονα, πλάγια και υπογραμμισμένα γράμματα.";
out.tips.indent = "Σε αριθμημένες λίστες όπως και λίστες με τελείες, μπορείτε να χρησιμοποιήσετε tab ή shift+tab για να αυξήσετε ή να μειώσετε τις εσοχές με γρήγορο τρόπο.";
out.tips.store = "Κάθε φορά που επισκέπτεστε ένα pad, εάν είσαστε συνδεδεμένοι, θα σώζεται αυτόματα στο CryptDrive σας.";
out.tips.marker = "Μπορείτε να υπογραμμίσετε κείμενο σε ένα pad χρησιμοποιώντας τον \"μαρκαδόρο\" από το μενού μορφoποίησης.";
out.tips.driveUpload = "Οι εγγεγραμένοι χρήστες μπορούν να ανεβάσουν κρυπτογραφημένα αρχεία σύροντάς τα και πετώντας τα στο CryptDrive τους.";
out.tips.filenames = "Μπορείτε να μετονομάσετε αρχεία στο CryptDrive σας. Το όνομα που θα δώσετε είναι μόνο για εσάς.";
out.tips.drive = "Οι συνδεδεμένοι χρήστες μπορούν να οργανώσουν τα αρχεία τους στο CryptDrive τους, τα οποία είναι προσβάσιμα από το εικονίδιο CryptPad που είναι πάνω αριστερά σε όλα τα pads.";
out.tips.profile = "Οι εγγεγραμένοι χρήστες μπορούν να δημιουργήσουν ένα προφίλ από το μενού χρήστη πάνω δεξιά.";
out.tips.avatars = "Μπορείτε να ανεβάσετε ένα άβαταρ στο προφίλ σας. Θα το βλέπουν οι άλλοι όταν συνεργάζεστε σε ένα pad.";
out.tips.tags = "Βάλτε ετικέτες στα pads σας και ψάξτε με # στο CryptDrive σας για να τα βρείτε";
out.feedback_about = "Εάν το διαβάζετε αυτό, πιθανότατα ήσασταν περίεργοι για ποιο λόγο το CryptPad ζητά ιστοσελίδες όταν κάνετε συγκεκριμένες ενέργειες";
out.feedback_privacy = "Ενδιαφερόμαστε για την ιδιωτικότητά σας και ταυτόχρονα θέλουμε το CryptPad να είναι πολύ εύκολο στην χρήση. Χρησιμοποιούμε αυτό το αρχείο για να καταλάβουμε ποια χαρακτηριστικά του περιβάλλοντος διάδρασης ενδιαφέρουν τους χρήστες μας, με το να το ζητήσουμε σε συνδυασμό με μια παράμετρο η οποία μας δείχνει συγκεκριμένα ποια ενέργεια έγινε.";
out.feedback_optout = "Εάν θα θέλατε να απέχετε, επισκεφθείτε <a href='/settings/'>τη σελίδα ρυθμίσεων</a> του λογαριασμού σας, όπου θα βρείτε ένα κουτί στο οποίο μπορείτε να ενεργοποιήσετε ή να απενεργοποιήσετε την αναπληροφόρηση";
return out;
});

View File

@ -0,0 +1,583 @@
/*
* This is an internal language file.
* If you want to change some translations in your CryptPad instance, use the '/customize/translations/messages.{LANG}.js'
* file (make a copy from /customize.dist/translations/messages.{LANG}.js)
*/
define(function () {
var out = {};
out._languageName = 'Español';
out.main_title = "Cryptpad: Zero Knowledge, Editor Colaborativo en Tiempo Real";
out.main_slogan = "La unidad es la fuerza - la colaboración es la clave";
out.type = {};
out.type.pad = 'Pad';
out.type.code = 'Código';
out.type.poll = 'Encuesta';
out.type.slide = 'Presentación';
out.type.whiteboard = 'Pizarra';
out.type.contacts = 'Contactos';
out.disconnected = "Desconectado";
out.synchronizing = "Sincronización";
out.reconnecting = "Reconectando...";
out.lag = "Retraso";
out.readonly = 'Sólo lectura';
out.anonymous = 'Anónimo';
out.yourself = "Tú mismo";
out.anonymousUsers = "usuarios anónimos";
out.anonymousUser = "usuario anónimo";
out.users = "Usuarios";
out.and = "y";
out.viewer = "espectador";
out.viewers = "espectadores";
out.editor = "editor";
out.editors = "editores";
out.greenLight = "Todo funciona bien";
out.orangeLight = "La conexión es lenta y podría afectar la experiencia";
out.redLight = "Has sido desconectado de la sesión";
out.importButtonTitle = 'Importar un documento de tus archivos locales';
out.exportButtonTitle = 'Exportar este documento a un archivo local';
out.exportPrompt = '¿Cómo te gustaría llamar a este archivo?';
out.changeNamePrompt = 'Cambiar tu nombre (dejar vacío para ser anónimo): ';
out.clickToEdit = "Haz clic para cambiar";
out.forgetButtonTitle = 'Eliminar este documento de la lista en la pagina de inicio';
out.forgetPrompt = 'Pulsar OK eliminará este documento del almacenamiento local (localStorage), ¿estás seguro?';
out.shareButton = 'Compartir';
out.shareSuccess = 'URL copiada al portapapeles';
out.presentButtonTitle = "Entrar en el modo presentación";
out.backgroundButtonTitle = 'Cambiar el color de fondo en el modo presentación';
out.colorButtonTitle = 'Cambiar el color de texto en el modo presentación';
out.editShare = "URL de edición compartida";
out.editShareTitle = "Copiar la URL de edición al portapapeles";
out.viewShare = "Compartir URL de sólo lectura";
out.viewShareTitle = "Copiar la URL de sólo lectura al portapapeles";
out.viewOpen = "Ver en pestaña nueva";
out.viewOpenTitle = "Abrir el documento en sólo lectura en una pestaña nueva";
out.notifyJoined = "{0} se ha unido a la sesión de colaboración";
out.notifyRenamed = "{0} ahora se conoce como {1}";
out.notifyLeft = "{0} ha dejado la sesión de colaboración";
out.tryIt = '¡Pruébalo!';
out.okButton = 'OK (Enter)';
out.cancelButton = 'Cancelar (Esc)';
// Polls
out.poll_title = "Selector de fecha Zero Knowledge";
out.poll_subtitle = "Agenda en <em>tiempo real</em> Zero Knowledge";
out.poll_p_save = "Tus configuraciones se actualizan instantáneamente, no es necesario guardar cambios.";
out.poll_p_encryption = "Todos los datos entrados son cifrados, sólo las personas que poseen el enlace tienen acceso. Incluso el servidor no puede ver el contenido.";
out.wizardLog = "Presiona el botón en la parte superior izquierda para volver a la encuesta";
out.wizardTitle = "Utiliza el asistente para crear tu encuesta";
out.wizardConfirm = "¿Estás realmente seguro de agregar estas opciones a tu encuesta?";
out.poll_closeWizardButton = "Cerrar el asistente";
out.poll_closeWizardButtonTitle = "Cerrar el asistente";
out.poll_wizardComputeButton = "Generar opciones";
out.poll_wizardClearButton = "Limpiar tabla";
out.poll_wizardDescription = "Crear opciones automáticamente ingresando cualquier cantidad de fechas y horas";
out.poll_wizardAddDateButton = "+ Fechas";
out.poll_wizardAddTimeButton = "+ Horas";
out.poll_optionPlaceholder = "Opción";
out.poll_userPlaceholder = "Tu nombre";
out.poll_removeOption = "¿Estás seguro de que quieres eliminar esta opción?";
out.poll_removeUser = "¿Estás seguro de que quieres eliminar este usuario?";
out.poll_titleHint = "Título";
out.poll_descriptionHint = "Descripción";
// index.html
out.main_p2 = 'Este proyecto utiliza el editor de texto visual <a href="http://ckeditor.com/">CKEditor</a>, <a href="https://codemirror.net/">CodeMirror</a>, y el motor en tiempo real <a href="https://github.com/xwiki-contrib/chainpad">ChainPad</a>.';
out.main_howitworks = '¿Cómo funciona?';
out.main_howitworks_p1 = "CryptPad utiliza una variante del algoritmo de <a href='https://en.wikipedia.org/wiki/Operational_transformation'>transformación operacional</a> (página en inglés) que es capaz de encontrar un consenso distribuido usando un <a href='https://bitcoin.org/bitcoin.pdf'>Blockchain Nakamoto</a> (página en inglés), popularizado por <a href='https://es.wikipedia.org/wiki/Bitcoin'>Bitcoin</a>. De esta manera el algoritmo puede evitar la necesidad de un servidor central para resolver conflictos de edición de la transformación operacional y sin necesidad de resolver conflictos, el servidor puede mantenerse inconsciente del contenido que se está editando en el pad.";
out.main_about_p2 = 'Si tienes preguntas o comentarios, puedes <a href="https://twitter.com/cryptpad"><i class="fa fa-twitter"></i>enviarnos un tweet</a>, abrir un issue <a href="https://github.com/xwiki-labs/cryptpad/issues/" title="nuestro issue tracker">en <i class="fa fa-github"></i>GitHub</a>. saludarnos en <a href="https://riot.im/app/#/room/#cryptpad:matrix.org" title="Matrix">nuestro <i class="fa fa-comment"></i>canal Matrix</a> o en IRC (#cryptpad on irc.freenode.net), o <a href="mailto:research@xwiki.com"><i class="fa fa-envelope"></i>envianos un email</a>.';
out.button_newpad = 'Crear nuevo pad de texto enriquecido';
out.button_newcode = 'Crear nuevo pad de código';
out.button_newpoll = 'Crear nueva encuesta';
out.button_newslide = 'Crear nueva presentación';
// privacy.html
out.policy_title = 'Política de privacidad Cryptpad';
out.policy_whatweknow = 'Qué sabemos sobre tí';
out.policy_whatweknow_p1 = 'Como cualquier aplicación que está en la red, Cryptpad tiene acceso a los metadatos expuestos por el protocolo HTTP. Esto incluye tu dirección IP, y otros headers HTTP que pueden ser utilizados para identificar a tu navegador propio. Puedes ver la información que comparte tu navegador visitando <a target="_blank" rel="noopener noreferrer" href="https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending" title="Qué headers HTTP esta compartiendo mi navegador">WhatIsMyBrowser.com</a> (página en inglés).';
out.policy_whatweknow_p2 = 'Nosotros usamos <a href="https://piwik.org/" target="_blank" rel="noopener noreferrer" title="open source analytics platform">Piwik</a>, una plataforma de analítica de datos abierta, para conocer mejor a nuestros usuarios. Piwik nos dice como encontraste Cryptpad, en entrada manual, por un motor de búsqueda, or por referal de otra página como Reddit o Twitter. También aprendemos cuándo visitas, qué páginas ves en nuestra web, y cuánto tiempo te quedas en cada una.';
out.policy_howweuse = 'Cómo usamos lo que aprendemos';
out.policy_howweuse_p1 = 'Usamos esta información para tomar mejores decisiones para promocionar Cryptpad, para evaluar cuáles de nuestros esfuerzos han sido exitosos. La información sobre tu ubicación nos permite saber si deberíamos considerar mejor soporte para idiomas diferentes al inglés.';
out.policy_howweuse_p2 = "La información sobre tu navegador (en escritorio o móvil) nos ayuda a saber qué características que debemos mejorar. Nuestro equipo de desarrollo es pequeño, e intentamos tomar decisiones que beneficien a la experiencia de la mayoría de nuestros usuarios.";
out.policy_whatwetell = 'Lo que decimos a otros sobre tí';
out.policy_whatwetell_p1 = 'No suministramos la información que recolectamos a terceros a menos de estar legalmente obligados a hacerlo.';
out.policy_links = 'Enlaces a otras páginas';
out.policy_links_p1 = 'Esta web contiene enlaces a otros sitios, incluyendo algunos producidos por otras organizaciones. No somos responsables del tratamiento de la privacidad de los datos ni el contenido de páginas externas. Como regla general, los enlaces externos se abren en una nueva pestaña del navegador, para clarificar que estás abandonando a Cryptpad.fr.';
out.policy_ads = 'Anuncios';
out.policy_ads_p1 = 'Nosotros no mostramos anuncios, pero podemos poner enlaces a las organizaciones que financian nuestro trabajo de investigación.';
out.policy_choices = 'Lo que puedes hacer';
out.policy_choices_open = 'Nuestro código fuente es abierto para que siempre tengas la opción de desplegar tu propia instancia de Cryptpad.';
out.policy_choices_vpn = 'Si deseas utilizar nuestra instancia, pero no deseas exponer tu dirección IP, puedes protegerla utilizando <a href="https://www.torproject.org/projects/torbrowser.html.en" title="descargas Tor project" target="_blank" rel="noopener noreferrer">el navegador Tor</a>, o un <a href="https://riseup.net/en/vpn" title="VPNs por Riseup" target="_blank" rel="noopener noreferrer">VPN</a>.';
out.policy_choices_ads = 'Si deseas no ser seguido por nuestra plataforma, puedes utilizar herramientas como <a href="https://www.eff.org/privacybadger" title="descargar a Privacy Badger" target="_blank" rel="noopener noreferrer">Privacy Badger</a>.';
// terms.html
out.tos_title = "Condiciones de servicio Cryptpad";
out.tos_legal = "Por favor, no seas malicioso, abusivo o hagas algo ilegal.";
out.tos_availability = "Esperamos que este servicio te parezca útil, pero nuestra disponibilidad o rendimiento no pueden ser garantizados. Por favor, exporta tus datos regularmente.";
out.tos_e2ee = "Los documentos Cryptpad pueden ser leídos o modificados por cualquiera que pueda adivinar o que pueda tener el enlace. Recomendamos que utilices mensajes cifrados de punto a punto (e2ee) para compartir URLs, no asumimos ninguna responsabilidad en el evento de alguna fuga.";
out.tos_logs = "Los metadatos entregados por el navegador al servidor pueden ser almacenados para la mantenencia del servicio.";
out.tos_3rdparties = "No proveemos datos individualizados a terceros a menos de ser obligados por la ley.";
// BottomBar.html
out.bottom_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Hecho con <img class="bottom-bar-heart" src="/customize/heart.png" alt="amor" /> en <img class="bottom-bar-fr" src="/customize/fr.png" alt="Francia" /></a>';
out.bottom_support = '<a href="http://labs.xwiki.com/" title="XWiki Labs" target="_blank" rel="noopener noreferrer">Un <img src="/customize/logo-xwiki2.png" alt="XWiki SAS" class="bottom-bar-xwiki"/>Proyecto Labs</a> con el soporte de <a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"><img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
// Header.html
out.header_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Con <img class="bottom-bar-heart" src="/customize/heart.png" alt="amor" /> de <img class="bottom-bar-fr" src="/customize/fr.png" title="France" alt="Francia"/> por <img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
out.header_support = '<a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferre-r"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
out.header_logoTitle = 'Ir a la página principal';
out.websocketError = "Error al conectarse al servidor WebSocket";
out.typeError = "Este documento no es compatible con la aplicación seleccionada";
out.onLogout = "Tu sesión está cerrada, {0}haz clic aquí{1} para iniciar sesión<br>o pulsa <em>Escape</em> para acceder al documento en modo sólo lectura.";
out.loading = "Cargando...";
out.error = "Error";
out.language = "Idioma";
out.user_rename = "Cambiar nombre";
out.user_displayName = "Nombre visible";
out.user_accountName = "Nombre de cuenta";
out.newButton = "Nuevo";
out.newButtonTitle = "Nuevo documento";
out.cancel = "Cancelar";
out.poll_publish_button = "Publicar";
out.poll_admin_button = "Administrar";
out.poll_create_user = "Añadir usuario";
out.poll_create_option = "Añadir opción";
out.poll_commit = "Validar";
out.fm_rootName = "Documentos";
out.fm_trashName = "Papelera";
out.fm_unsortedName = "Sin organizar";
out.fm_filesDataName = "Todos los archivos";
out.fm_templateName = "Plantilla";
out.fm_newButton = "Nuevo";
out.fm_newFolder = "Nueva carpeta";
out.fm_folder = "Carpeta";
out.fm_folderName = "Nombre de carpeta";
out.fm_numberOfFolders = "# de carpetas";
out.fm_numberOfFiles = "# de archivos";
out.fm_fileName = "Nombre";
out.fm_title = "Título";
out.fm_lastAccess = "Último acceso";
out.fm_creation = "Creación";
out.fm_forbidden = "Acción prohibida";
out.fm_originalPath = "Enlace original";
out.fm_noname = "Documento sin título";
out.fm_emptyTrashDialog = "¿Seguro que quieres vaciar la papelera?";
out.fm_removeSeveralPermanentlyDialog = "¿Seguro que quieres eliminar estos {0} elementos de la papelera para siempre?";
out.fm_removePermanentlyDialog = "¿Seguro que quieres eliminar este elemento para siempre?";
out.fm_removeSeveralDialog = "¿Seguro que quieres mover estos {0} elementos a la papelera?";
out.fm_removeDialog = "¿Seguro que quieres mover {0} a la papelera?";
out.fm_restoreDialog = "¿Seguro que quieres recuperar {0}?";
out.fm_unknownFolderError = "La carpeta seleccionada ya no existe. Abriendo la carpeta anterior...";
out.fm_contextMenuError = "No se pudo abrir el menú para este elemento. Si persiste el problema, recarga la página.";
out.fm_selectError = "No se pudo abrir el elemento. Si persiste el problema, recarga la página.";
out.fm_info_root = "Crea carpetas aquí para organizar tus documentos.";
out.fm_info_unsorted = "Contiene todos los documentos que has visitado que no están organizados en \"Documentos\" o movidos a la \"Papelera\".";
out.fm_info_template = "Contiene todas las plantillas que puedes volver a usar para crear nuevos documentos.";
out.fm_info_allFiles = "Contiene todos los archivos de \"Documentos\", \"Sin organizar\" y \"Papelera\". No puedes mover o eliminar archivos aquí.";
out.fm_alert_backupUrl = "Enlace de copia de seguridad para este drive. Te recomendamos <strong>encarecidamente</strong> que lo guardes secreto.<br>Lo puedes usar para recuperar todos tus archivos en el caso que la memoria de tu navegador se borre.<br>Cualquiera con este enlace puede editar o eliminar todos los archivos en el explorador.<br>";
out.fm_backup_title = "Enlace de copia de seguridad";
out.fm_nameFile = "¿Cómo quieres nombrar este archivo?";
out.fc_newfolder = "Nueva carpeta";
out.fc_rename = "Cambiar nombre";
out.fc_open = "Abrir";
out.fc_open_ro = "Abrir (sólo lectura)";
out.fc_delete = "Eliminar";
out.fc_restore = "Recuperar";
out.fc_remove = "Eliminar para siempre";
out.fc_empty = "Vaciar la papelera";
out.fc_prop = "Propiedades";
out.fo_moveUnsortedError = "No puedes mover una carpeta en la lista de documentos no organizados";
out.fo_existingNameError = "Nombre ya utilizado en esta carpeta. Por favor elige otro.";
out.fo_moveFolderToChildError = "No puedes mover una carpeta en una de sus subcarpetas";
out.fo_unableToRestore = "No se pudo restaurar este archivo a la localización de origen. Puedes intentar moverlo a otra localización.";
out.fo_unavailableName = "Un archivo o carpeta ya tiene este nombre. Cámbialo y vuelve a intentarlo.";
out.login_login = "Iniciar sesión";
out.login_makeAPad = "Crear documento anónimo";
out.login_nologin = "Ver documentos locales";
out.login_register = "Registrarse";
out.logoutButton = "Cerrar sesión";
out.settingsButton = "Preferencias";
out.login_username = "Nombre de usuario";
out.login_password = "Contraseña";
out.login_confirm = "Confirmar contraseña";
out.login_remember = "Recuérdame";
out.login_hashing = "Generando hash de tu contraseña, esto puede tardar un poco.";
out.login_hello = "Hola {0},";
out.login_helloNoName = "Hola,";
out.login_accessDrive = "Acceder a tu drive";
out.login_orNoLogin = "o";
out.login_noSuchUser = "Credenciales inválidos. Inténtalo de nuevo, o regístrate";
out.login_invalUser = "Nombre de usuario requerido";
out.login_invalPass = "Contraseña requerida";
out.login_unhandledError = "Ha ocurrido un error inesperado :(";
out.register_importRecent = "Importe el historial de tu sesión anónima";
out.register_acceptTerms = "Acepto los <a href='/terms.html' tabindex='-1'>términos de servicio</a>";
out.register_passwordsDontMatch = "Las contraseñas no corresponden";
out.register_mustAcceptTerms = "Tienes que aceptar los términos de servicio";
out.register_mustRememberPass = "No podemos reiniciar tu contraseña si la olvidas. ¡Es muy importante que la recuerdes! Marca la casilla para confirmarlo.";
out.register_header = "Bienvenido a CryptPad";
out.register_explanation = ["<p>Vamos a ver algunas cosas antes</p>", "<ul>", "<li>Tu contraseña es tu clave secreta que cifra todos tus documentos. Si la pierdes no podremos recuperar tus datos.</li>", "<li>Puedes importar documentos que has visto recientemente en tu navegador para tenerlos en tu cuenta.</li>", "<li>Si estás usando un ordenador compartido, tienes que cerrar sesión cuando terminas, cerrar la pestaña no es suficiente.</li>", "</ul>"].join('');
out.settings_title = "Preferencias";
out.settings_save = "Guardar";
out.settings_backupTitle = "Copia de seguridad";
out.settings_backup = "Copia de seguridad";
out.settings_restore = "Recuperar datos";
out.settings_reset = "Quita todos los documentos de tu CryptDrive";
out.settings_resetPrompt = "Esta acción eliminará todos tus documentos.<br>¿Seguro que quieres continuar?<br>Introduce “<em>I love CryptPad</em>” para confirmar.";
out.settings_resetDone = "¡Tu drive ahora está vacio!";
out.settings_resetTips = "Consejos en CryptDrive";
out.settings_resetTipsButton = "Restaurar consejos";
out.settings_resetTipsDone = "Todos los consejos ahora están visibles";
out.main_info = "<h1>Colabora con Confianza</h1><br>Cultiva ideas juntos con documentos compartidos con tecnología <strong>Zero Knowledge</strong> que protege tu privacidad.";
out.main_zeroKnowledge = "Zero Knowledge";
out.main_zeroKnowledge_p = "No tienes que confiar en que <em>no</em> veremos tus documentos, con la tecnología Zero Knowledge de CryptPad <em>no podemos</em>. Aprende más sobre cómo protegemos tu <a href=\"/privacy.html\" title='Privacidad'>Privacidad y Seguridad</a>.";
out.main_writeItDown = "Escríbelo";
out.main_writeItDown_p = "Los mejores proyectos vienen de las más pequeñas ideas. Escribe tus momentos de inspiración e ideas inesperadas porque nunca sabrás cuál será tu próximo descubrimiento.";
out.main_share = "Comparte el enlace, comparte el pad";
out.main_share_p = "Cultiva ideas juntos: ten reuniones eficaces, colabora en listas y haz presentaciones rápidas en todos tus dispositivos.";
out.main_organize = "Organízate";
out.main_organize_p = "Con CryptPad Drive, mantén tu atención en lo más importante. Las carpetas te permiten organizar tus proyectos y tener una visión global de dónde van las cosas.";
out.main_richText = "Editor de Texto Enriquecido";
out.main_richText_p = "Colabora en texto enriquecido con nuestro editor Zero Knowledge en tiempo real <a href=\"http://ckeditor.com\" target=\"_blank\">CkEditor</a>.";
out.main_code = "Editor de código";
out.main_code_p = "Edita código fuente para tus programas con nuestro editor Zero Knowledge en tiempo real <a href=\"https://www.codemirror.net\" target=\"_blank\">CodeMirror</a>.";
out.main_slide = "Editor de presentación";
out.main_slide_p = "Crea presentaciones utilizando Markdown, y visualízalos en tu navegador";
out.main_poll = "Encuestas";
out.main_poll_p = "Planifica tus reuniones y eventos, o vota para la mejor solución a un problema.";
out.main_drive = "CryptDrive";
out.footer_applications = "Aplicaciones";
out.footer_contact = "Contacto";
out.footer_aboutUs = "Acerca de nosotros";
out.about = "Acerca de nosotros";
out.privacy = "Privacidad";
out.contact = "Contacto";
out.terms = "Términos de Servicio";
// 1.1.0 - Bunyip
out.movedToTrash = "Este pad fue movido a la papelera.<br><a href\"/drive/\">Acceder a mi Drive</a>";
out.fm_newFile = "Nuevo pad";
out.fm_type = "Tipo";
out.fm_categoryError = "No se pudo abrir la categoría seleccionada, mostrando la raíz.";
out.settings_userFeedbackHint1 = "CryptPad suministra informaciones muy básicas al servidor, para ayudarnos a mejorar vuestra experiencia.";
out.settings_userFeedbackHint2 = "El contenido de tu pad nunca será compartido con el servidor.";
out.settings_userFeedback = "Activar feedback";
out.settings_anonymous = "No has iniciado sesión. Tus ajustes se aplicarán sólo a este navegador.";
out.blog = "Blog";
out.initialState = [
'<p>',
'Esto es&nbsp;<strong>CryptPad</strong>, el editor colaborativo en tiempo real Zero Knowledge. Todo está guardado cuando escribes.',
'<br>',
'Comparte el enlace a este pad para editar con amigos o utiliza el botón <span class="fa fa-share-alt"></span> para obtener un <em>enlace sólo lectura</em>&nbsp;que permite leer pero no escribir.',
'</p>',
].join('');
out.codeInitialState = "/*\n Esto es CryptPad, el editor colaborativo en tiempo real zero knowledge.\n Lo que escribes aquí está cifrado de manera que sólo las personas con el enlace pueden acceder a ello.\n Incluso el servidor no puede ver lo que escribes.\n Lo que ves aquí, lo que escuchas aquí, cuando sales, se queda aquí\n*/";
out.slideInitialState = "# CryptSlide\n1. Escribe tu contenido en Markdown\n - Puedes aprender más sobre Markdown [aquí](http://www.markdowntutorial.com/)\n2. Separa tus diapositivas con ---\n3. Haz clic en \"Presentar\" para ver el resultado - Tus diapositivas se actualizan en tiempo real";
out.driveReadmeTitle = "¿Qué es CryptPad?";
out.readme_welcome = "¡Bienvenido a CryptPad!";
out.readme_p1 = "Bienvenido a CryptPad, aquí podrás anotar cosas solo o con otra gente.";
out.readme_p2 = "Este pad es una guía rápida para aprender a usar a CryptPad para tomar notas, organizarlas y trabajar con más personas.";
out.readme_cat1 = "Conoce tu CryptDrive";
out.readme_cat1_l1 = "Crea un pad: En CryptDrive, haz clic en {0} y luego en {1} para crear un pad.";
out.readme_cat1_l2 = "Abrir pads desde CryptDrive: haz doble clic en un icono para abrirlo.";
out.readme_cat1_l3 = "Organiza tus pads: Cuando has iniciado sesión, cada pad al que accedes se quedará en tu drive en {0}.";
out.readme_cat1_l3_l1 = "Puedes hacer clic y arrastrar archivos en carpetas desde {0}, y crear nuevas carpetas.";
out.readme_cat1_l3_l2 = "Recuerda hacer clic derecho en los iconos, ya que suele haber menús adicionales.";
out.readme_cat1_l4 = "Elimina tus viejos pads: Haz clic y arrastra tus pads en la {0} de la misma manera que lo harías con carpetas.";
out.readme_cat2 = "Haz pads como un pro";
out.edit = "editar";
out.view = "ver";
out.readme_cat2_l1 = "El botón {0} en tu pad te permite dar acceso a colaboradores para {1} o {2} el pad.";
out.readme_cat2_l2 = "Cambia el título del pad haciendo clic en el lápiz";
out.readme_cat3 = "Descubre las apps CryptPad";
out.readme_cat3_l1 = "Con el editor de código CryptPad, puedes colaborar en código fuente, como por ejemplo JavaScript y Markdown";
out.readme_cat3_l2 = "Con los slides CryptPad, puedes hacer presentaciones rápidas con Markdown";
out.readme_cat3_l3 = "Con CryptPoll puedes hacer una encuesta rápida, especialmente útil para programar un horario que conviene a todo el mundo";
// 1.2.0 - Chupacabra
out.settings_resetError = "Verificación no válida. Tu CryptDrive no fue cambiado.";
out.saved = "Guardado";
out.printButton = "Imprimir";
out.printButtonTitle = "Imprimir tu presentación o exportar a PDF";
out.printOptions = "Opciones de impresión";
out.printSlideNumber = "Mostrar el número de diapositiva";
out.printDate = "Mostrar la fecha";
out.printTitle = "Mostrar el título";
out.printCSS = "CSS personalizado:";
out.editOpen = "Abrir enlaces de edición en pestaña nueva";
out.editOpenTitle = "Abrir en modo edición en pestaña nueva";
out.settings_importTitle = "Importar pads recientes locales en CryptDrive";
out.settings_import = "Importar";
out.settings_importConfirm = "¿Seguro que quieres importar tus pads recientes a tu cuenta CryptDrive?";
out.settings_importDone = "Importación terminada";
out.tips = {};
out.tips.lag = "El icono verde en la parte superior derecha muestra la calidad de tu connexión a CryptPad.";
out.tips.shortcuts = "`ctrl+b`, `ctrl+i`, y `ctrl+u` son accesos rápidos para negrita, itálica y subrayado.";
out.tips.indent = "Cuando editas listas, puedes usar tab o shift+tab para incrementar o decrementar la sangría.";
out.tips.title = "Puedes cambiar el título de tus pads en la parte superior de la pantalla.";
out.tips.store = "Cada vez que visitas un pad con una sesión iniciada se guardará en tu CryptDrive.";
out.tips.marker = "Puedes resaltar texto en un pad utilizando el \"marcador\" en el menú de estílo.";
out.tips.driveUpload = "Los usuarios registrados pueden subir archivos cifrados arrastrándolos hacia CryptDrive.";
out.feedback_about = "Si estas leyendo esto, quizás sientas curiosidad por saber por qué CryptPad solicita páginas cuando realizas algunas acciones";
out.feedback_privacy = "Nos importa tu privacidad, y al mismo tiempo queremos que CryptPad sea muy fácil de usar. Utilizamos este archivo para conocer las funcionalidades que importan a nuestros usuarios, pidiéndolo con un parametro que nos dice qué acción fue realizada.";
out.feedback_optout = "Si quieres darte de baja, visita <a href='/settings/'>tus preferencias</a>, donde podrás activar o desactivar el feedback";
out.fm_searchName = "Buscar";
out.fm_searchPlaceholder = "Buscar...";
out.fm_newButtonTitle = "Crear un nuevo pad o carpeta";
out.fm_openParent = "Mostrar en carpeta";
out.register_writtenPassword = "He escrito mi usuario y contraseña, continuar";
out.register_cancel = "Volver";
out.register_warning = "Zero Knowledge significa que no podemos recuperar tus datos si pierdes tu contraseña.";
out.register_alreadyRegistered = "Este usuario ya existe, ¿iniciar sesión?";
// 1.4.0 - Easter Bunny
out.button_newwhiteboard = "Nueva Pizarra";
out.wrongApp = "No se pudo mostrar el contenido de la sesión en tiempo real en tu navegador. Por favor, actualiza la página.";
out.synced = "Todo está guardado.";
out.saveTemplateButton = "Guardar como plantilla";
out.saveTemplatePrompt = "Elige un título para la plantilla";
out.templateSaved = "¡Plantilla guardada!";
out.selectTemplate = "Elige una plantilla o pulsa ESC";
out.slideOptionsTitle = "Personaliza tus diapositivas";
out.slideOptionsButton = "Guardar (enter)";
out.canvas_clear = "Limpiar";
out.canvas_delete = "Borrar selección";
out.canvas_disable = "No permitir dibujos";
out.canvas_enable = "Permitir dibujos";
out.canvas_width = "Talla";
out.canvas_opacity = "Opacidad";
out.settings_publicSigningKey = "Clave de Firma Pública";
out.settings_usage = "Utilización";
out.settings_usageTitle = "Ve el uso total de tus pads en MB";
out.settings_pinningNotAvailable = "Los pads pegados sólo están disponibles para usuarios registrados.";
out.settings_pinningError = "Algo salió mal";
out.settings_usageAmount = "Tus pads pegados utilizan {0}MB";
out.historyButton = "Mostrar el historial del documento";
out.history_next = "Ir a la versión anterior";
out.history_prev = "Ir a la versión posterior";
out.history_goTo = "Ir a la versión seleccionada";
out.history_close = "Volver";
out.history_closeTitle = "Cerrar el historial";
out.history_restore = "Restaurar";
out.history_restoreTitle = "Restaurar la versión seleccionada del documento";
out.history_restorePrompt = "¿Estás seguro de que quieres cambiar la versión actual del documento por ésta?";
out.history_restoreDone = "Documento restaurado";
out.fc_sizeInKilobytes = "Tamaño en Kilobytes";
// 1.5.0/1.6.0 - Fenrir/Grootslang
out.deleted = "El pad fue borrado de tu CryptDrive";
out.upgrade = "Mejorar";
out.upgradeTitle = "Mejora tu cuenta para obtener más espacio";
out.upgradeAccount = "Mejorar cuenta";
out.MB = "MB";
out.GB = "GB";
out.KB = "KB";
out.formattedMB = "{0} MB";
out.formattedGB = "{0} GB";
out.formattedKB = "{0} KB";
out.pinLimitReached = "Has llegado al límite de espacio";
out.pinLimitNotPinned = "Has llegado al límite de espacio.<br>Este pad no estará presente en tu CryptDrive.";
out.pinLimitDrive = "Has llegado al límite de espacio.<br>No puedes crear nuevos pads.";
out.printTransition = "Activar transiciones";
out.history_version = "Versión: ";
out.settings_logoutEverywhereTitle = "Cerrar sesión en todas partes";
out.settings_logoutEverywhere = "Cerrar todas las otras sesiones";
out.settings_logoutEverywhereConfirm = "¿Estás seguro? Tendrás que volver a iniciar sesión con todos tus dispositivos.";
out.upload_serverError = "Error: no se pudo subir tu archivo en este momento.";
out.upload_uploadPending = "Ya tienes una subida en progreso. ¿Cancelar y subir el nuevo archivo?";
out.upload_success = "Tu archivo ({0}) ha sido subido con éxito y fue añadido a tu drive.";
// 1.7.0 - Hodag
out.comingSoon = "Próximamente...";
out.newVersion = ["<b>CryptPad ha sido actualizado!</b>",
"Puedes ver lo que ha cambiado aquí (en inglés):",
"<a href=\"https://github.com/xwiki-labs/cryptpad/releases/tag/{0}\" target=\"_blank\">Notas de versión para CryptPad {0}</a>"].join("<br>");
out.pinLimitReachedAlertNoAccounts = "Has llegado a tu límite de espacio";
out.previewButtonTitle = "Mostrar/esconder la vista previa Markdown";
out.fm_info_anonymous = "No estás conectado, así que estos pads pueden ser borrados (<a href=\"https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/\" target=\"_blank\">¿por qué?</a>). <a href=\"/register/\">Regístrate</a> o <a href=\"/login/\">Inicia sesión</a> para asegurarlos.";
out.fm_alert_anonymous = "Hola, estás usando CryptPad anónimamente. Está bien, pero tus pads pueden ser borrados después de un périodo de inactividad. Hemos desactivado funciones avanzadas de CryptDrive para usuarios anónimos porque queremos dejar claro que no es un lugar seguro para almacenar cosas. Puedes <a href=\"https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/\" target=\"_blank\">leer este articulo</a> (en inglés) acerca de por qué hacemos esto y por qué deberías <a href=\"/register/\">Registrarte</a> e <a href=\"/login/\">Iniciar sesión</a>.";
out.fm_error_cantPin = "Error del servidor. Por favor, recarga la página e inténtalo de nuevo.";
out.upload_notEnoughSpace = "No tienes suficiente espacio para este archivo en tu CryptDrive";
out.upload_tooLarge = "Este archivo supera el límite de carga.";
out.upload_choose = "Escoge un archivo";
out.upload_pending = "Esperando";
out.upload_cancelled = "Cancelado";
out.upload_name = "Nombre";
out.upload_size = "Tamaño";
out.upload_progress = "Progreso";
out.download_button = "Descifrar y descargar";
out.warn_notPinned = "Este pad no está en ningún CryptDrive. Expirará después de 3 meses. <a href='/about.html#pinning'>Acerca de...</a>";
out.poll_remove = "Quitar";
out.poll_edit = "Editar";
out.poll_locked = "Cerrado";
out.poll_unlocked = "Abierto";
out.poll_show_help_button = "Mostrar ayuda";
out.poll_hide_help_button = "Esconder ayuda";
// 1.8.0 - Idopogo
out.common_connectionLost = "<b>Conexión perdida</b><br>El documento está ahora en modo sólo lectura hasta que la conexión vuelva.";
out.updated_0_common_connectionLost = out.common_connectionLost;
out.supportCryptpad = "Ayudar a CryptPad";
out.pinLimitReachedAlert = ["Has llegado a tu límite de espacio. Los nuevos pads no serán guardados en tu CryptDrive.",
"Puedes eliminar pads de tu CryptDrive o <a href=\"https://accounts.cryptpad.fr/#!on={0}\" target=\"_blank\">suscribirte a una oferta premium</a> para obtener más espacio."].join("<br>");
out.updated_0_pinLimitReachedAlert = out.pinLimitReachedAlert;
out.fm_info_trash = "Vacía tu papelera para liberar espacio en tu CryptDrive.";
out.updated_0_fm_info_trash = out.fm_info_trash;
out.fs_migration = "Tu CryptDrive fue actualizado a una nueva versión.<br><strong>Por favor, recarga la página.</strong>";
out.login_notRegistered = "¿No estás registrado?";
out.upload_mustLogin = "Tienes que estar conectado para subir archivos";
out.uploadButton = "Subir";
out.uploadButtonTitle = "Subir un archivo a la carpeta";
out.filePickerButton = "Incrustar un archivo";
out.filePicker_close = "Cerrar";
out.filePicker_description = "Elige un archivo de tu CryptDrive para incrustarlo o sube uno nuevo";
out.filePicker_filter = "Filtrar por nombre";
out.or = "o";
out.languageButton = "Lenguaje";
out.languageButtonTitle = "Elige el lenguaje para resaltado de sintaxis";
out.themeButton = "Tema";
out.themeButtonTitle = "Selecciona el tema de color para los editores de código y presentación";
out.canvas_opacityLabel = "Opacidad: {0}";
out.canvas_widthLabel = "Talla: {0}";
// 1.10.0 - Kraken
out.moreActions = "Más acciones";
out.importButton = "Importar";
out.exportButton = "Exportar";
out.saveTitle = "Guardar título (enter)";
out.forgetButton = "Eliminar";
out.printText = "Imprimir";
out.slideOptionsText = "Opciones";
out.historyText = "Historial";
out.openLinkInNewTab = "Abrir enlace en pestaña nueva";
out.profileButton = "Perfil";
out.profile_urlPlaceholder = "URL";
out.profile_namePlaceholder = "Nombre mostrado en su perfil";
out.profile_avatar = "Imagen";
out.profile_upload = "Subir una imagen";
out.profile_error = "Error al crear tu perfil: {0}";
out.profile_register = "Tienes que registrarte para crear un perfil";
out.profile_create = "Crear perfil";
out.profile_description = "Descripción";
out.profile_fieldSaved = "Guardado: {0}";
out.download_mt_button = "Descargar";
out.updated_0_header_logoTitle = "Volver a tu CryptDrive";
out.header_logoTitle = out.updated_0_header_logoTitle;
// 1.11.0 - Lutin
out.realtime_unrecoverableError = "El motor de tiempo real ha encontrado un error. Haga clic en OK para recargar la página.";
out.typing = "Escribiendo";
out.profile_inviteButton = "Conectar";
out.profile_inviteButtonTitle = "Crear un enlace de invitación para este usuario.";
out.profile_inviteExplanation = "Hacer clic en <strong>OK</strong> creará un enlace de mensaje seguro que <em>sólo {0} podrá ver.</em><br><br>El enlace será copiado a tu portapapeles y puede ser compartido públicamente.";
out.profile_viewMyProfile = "Ver mi perfil";
out.userlist_addAsFriendTitle = 'Agregar "{0}" como contacto';
out.userlist_thisIsYou = 'Tú mismo ("{0}")';
out.contacts_title = "Contactos";
out.contacts_addError = "Error al agregar este contacto a la lista";
out.contacts_added = "Invitación aceptada";
out.contacts_rejected = "Invitación denegada";
out.contacts_request = "<em>{0}</em> quiere agregarte como contacto. ¿<b>Aceptar</b>?";
out.contacts_send = "Enviar";
out.contacts_remove = "Eliminar este contacto";
out.contacts_confirmRemove = "¿Estás seguro de que quieres eliminar <em>{0}</em> de tus contactos?";
out.contacts_info1 = "Estos son tus contactos. Desde aquí, puedes:";
out.contacts_info2 = "Hacer clic en el icono de tu contacto para chatear";
out.contacts_info3 = "Hacer doble-clic para ver su perfil";
out.contacts_info4 = "Cualquier participante puede eliminar definitivamente el historial de chat";
out.settings_cat_account = "Cuenta";
out.settings_cat_drive = "CryptDrive";
out.settings_backupCategory = "Copia de seguridad";
out.settings_resetNewTitle = "Limpiar CryptDrive";
out.settings_resetButton = "Eliminar";
out.settings_resetTipsAction = "Reiniciar";
out.settings_userFeedbackTitle = "Feedback";
out.settings_logoutEverywhereButton = "Cerrar sesión";
out.upload_title = "Subir archivo";
// 1.12.0 - Minotaur
out.userlist_pending = "Pendiente...";
out.contacts_typeHere = "Escribe un mensaje aquí...";
out.contacts_removeHistoryTitle = "Borrar el historial de chat";
out.contacts_confirmRemoveHistory = "¿Estás seguro de que quieres borrar el historial de forma permanente? No se podrán recuparar los datos.";
out.contacts_removeHistoryServerError = "Hubo un error al borrar el historial. Inténtalo de nuevo más tarde.";
out.todo_title = "CryptTodo";
out.todo_newTodoNamePlaceholder = "Describe tu tarea...";
out.todo_newTodoNameTitle = "Añadir tarea a la lista";
out.todo_markAsCompleteTitle = "Marcar esta tarea como completa";
out.todo_markAsIncompleteTitle = "Marcar esta tarea como incompleta";
out.todo_removeTaskTitle = "Borrar esta tarea de la lista";
// 1.13.0 - Naiad
out.topbar_whatIsCryptpad = "Qué es CryptPad";
out.header_homeTitle = "Volver a la página de inicio";
out.userListButton = "Lista de usuarios";
out.userAccountButton = "Tu cuenta";
out.canvas_saveToDrive = "Guardar esta imagen como archivo en tu CryptDrive";
out.canvas_currentBrush = "Pincel actual";
out.canvas_chooseColor = "Eligir un color";
out.fm_viewListButton = "Lista";
out.fm_viewGridButton = "Cuadrícula";
out.settings_cat_code = "Código";
out.settings_codeIndentation = "Indentación del editor de código (espacios)";
out.settings_codeUseTabs = "Utilizar tabulaciones en vez de espacios";
out.pad_showToolbar = "Mostrar la barra de herramientas";
out.pad_hideToolbar = "Esconder la barra de herramientas";
out.main_catch_phrase = "El Cloud Zero Knowledge";
out.main_richTextPad = "Pad de Texto Enriquecido";
out.main_codePad = "Pad de Código";
out.main_slidePad = "Presentación Markdown";
out.main_pollPad = "Encuesta";
out.main_whiteboardPad = "Pizarra";
out.main_localPads = "Pad Locales";
out.main_yourCryptDrive = "Tu CryptDrive";
return out;
});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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