diff options
124 files changed, 2060 insertions, 579 deletions
@@ -18,3 +18,4 @@ npm-debug.log *.key bin/etherpad-1.deb credentials.json +out/ diff --git a/.travis.yml b/.travis.yml index 4cdf6383..908aca41 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,7 @@ node_js: install: - "bin/installDeps.sh" - "export GIT_HASH=$(git rev-parse --verify --short HEAD)" -before_script: - - "tests/frontend/travis/sauce_tunnel.sh" + - "npm install ep_test_line_attrib" script: - "tests/frontend/travis/runner.sh" env: diff --git a/CHANGELOG.md b/CHANGELOG.md index b4120a3c..63b970b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -#1.6.1 +# 1.6.1 * NEW: Hook aceRegisterNonScrollableEditEvents to register events that shouldn't scroll * NEW: Added 'item' parameter to registerAceCommand Hook * NEW: Added LibreJS support diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b6e1c247..09ddc286 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,7 @@ * Please be polite, we all are humans and problems can occur. * Please add as much information as possible, for example * client os(s) and version(s) - * browser(s) and version(s), is the problem reproduceable on different clients + * browser(s) and version(s), is the problem reproducible on different clients * special environments like firewalls or antivirus * host os and version * npm and nodejs version @@ -49,7 +49,7 @@ Also, keep it maintainable. We don't wanna end up as the monster Etherpad was! * Make small pull requests that are easy to review but make sure they do add value by themselves / individually ## Coding style -* Do write comments. (You don't have to comment every line, but if you come up with something thats a bit complex/weird, just leave a comment. Bear in mind that you will probably leave the project at some point and that other people will read your code. Undocumented huge amounts of code are worthless!) +* Do write comments. (You don't have to comment every line, but if you come up with something that's a bit complex/weird, just leave a comment. Bear in mind that you will probably leave the project at some point and that other people will read your code. Undocumented huge amounts of code are worthless!) * Never ever use tabs * Indentation: JS/CSS: 2 spaces; HTML: 4 spaces * Don't overengineer. Don't try to solve any possible problem in one step, but try to solve problems as easy as possible and improve the solution over time! @@ -79,7 +79,7 @@ see git flow http://nvie.com/posts/a-successful-git-branching-model/ ### feature branches (in your own repos) * these are the branches where you develop your features in -* If its ready to go out, it will be merged into develop +* If it's ready to go out, it will be merged into develop Over the time we pull features from feature branches into the develop branch. Every month we pull from develop into master. Bugs in master get fixed in hotfix branches. These branches will get merged into master AND develop. There should never be commits in master that aren't in develop @@ -3,7 +3,7 @@ outdoc_files = $(addprefix out/,$(doc_sources:.md=.html)) docassets = $(addprefix out/,$(wildcard doc/assets/*)) -VERSION = $(shell node -e "console.log( require('./src/package.json').version )") +VERSION = $(shell node -e "console.log( require('./src/package.json').version )") UNAME := $(shell uname -s) docs: $(outdoc_files) $(docassets) @@ -1,5 +1,5 @@ # A really-real time collaborative word processor for the web -![alt text](http://i.imgur.com/zYrGkg3.gif "Etherpad in action on PrimaryPad") +![alt text](https://i.imgur.com/zYrGkg3.gif "Etherpad in action on PrimaryPad") # About Etherpad is a really-real time collaborative editor maintained by the Etherpad Community. @@ -11,7 +11,7 @@ that allows your web application to manage pads, users and groups. It is recomme There is also a [jQuery plugin](https://github.com/ether/etherpad-lite-jquery-plugin) that helps you to embed Pads into your website. -There's also a full-featured plugin framework, allowing you to easily add your own features. By default your Etherpad is rather sparse and because Etherpad takes a lot of it's inspiration from Wordpress plugins are really easy to install and update. Once you have Etherpad installed you should visit the plugin page and take control. +There's also a full-featured plugin framework, allowing you to easily add your own features. By default your Etherpad is rather sparse and because Etherpad takes a lot of its inspiration from WordPress, plugins are really easy to install and update. Once you have Etherpad installed you should visit the plugin page and take control. Finally, Etherpad comes with translations into most languages! Users are automatically delivered the correct language for their local settings. @@ -35,7 +35,7 @@ This package works out of the box on any windows machine, but it's not very usef Now, run `start.bat` and open <http://localhost:9001> in your browser. You like it? [Next steps](#next-steps). ### Fancy install -You'll need [node.js](http://nodejs.org) and (optionally, though recommended) git. +You'll need [node.js](https://nodejs.org) and (optionally, though recommended) git. 1. Grab the source, either - download <https://github.com/ether/etherpad-lite/zipball/master> @@ -58,9 +58,9 @@ If cloning to a subdirectory within another project, you may need to do the foll You'll need gzip, git, curl, libssl develop libraries, python and gcc. - *For Debian/Ubuntu*: `apt-get install gzip git curl python libssl-dev pkg-config build-essential` - *For Fedora/CentOS*: `yum install gzip git curl python openssl-devel && yum groupinstall "Development Tools"` -- *For FreeBSD*: `portinstall node, npm, git (optional)` +- *For FreeBSD*: `portinstall node, npm, curl, git (optional)` -Additionally, you'll need [node.js](http://nodejs.org) installed, Ideally the latest stable version, we recommend installing/compiling nodejs from source (avoiding apt). +Additionally, you'll need [node.js](https://nodejs.org) installed, Ideally the latest stable version, we recommend installing/compiling nodejs from source (avoiding apt). **As any user (we recommend creating a separate user called etherpad):** @@ -92,9 +92,9 @@ Documentation can be found in `docs/`. # Development ## Things you should know -Understand [git](https://training.github.com/) and watch this [video on getting started with Etherpad Development](http://youtu.be/67-Q26YH97E). +Understand [git](https://training.github.com/) and watch this [video on getting started with Etherpad Development](https://youtu.be/67-Q26YH97E). -If you're new to node.js, start with Ryan Dahl's [Introduction to Node.js](http://youtu.be/jo_B4LTHi3I). +If you're new to node.js, start with Ryan Dahl's [Introduction to Node.js](https://youtu.be/jo_B4LTHi3I). You can debug Etherpad using `bin/debugRun.sh`. @@ -108,7 +108,7 @@ Look at the [TODO list](https://github.com/ether/etherpad-lite/wiki/TODO) and ou Also, and most importantly, read our [**Developer Guidelines**](https://github.com/ether/etherpad-lite/blob/master/CONTRIBUTING.md), really! # Get in touch -Join the [mailinglist](http://groups.google.com/group/etherpad-lite-dev) and make some noise on our busy freenode irc channel [#etherpad-lite-dev](http://webchat.freenode.net?channels=#etherpad-lite-dev)! +Join the [mailinglist](https://groups.google.com/group/etherpad-lite-dev) and make some noise on our busy freenode irc channel [#etherpad-lite-dev](https://webchat.freenode.net?channels=#etherpad-lite-dev)! # Modules created for this project @@ -117,9 +117,9 @@ Join the [mailinglist](http://groups.google.com/group/etherpad-lite-dev) and mak * [async-stacktrace](https://github.com/Pita/async-stacktrace) "Improves node.js stacktraces and makes it easier to handle errors" # Donate! -* [Flattr] (http://flattr.com/thing/71378/Etherpad-Foundation) +* [Flattr](https://flattr.com/thing/71378/Etherpad-Foundation) * Paypal - Press the donate button on [etherpad.org](http://etherpad.org) -* [Bitcoin] (https://coinbase.com/checkouts/1e572bf8a82e4663499f7f1f66c2d15a) +* [Bitcoin](https://coinbase.com/checkouts/1e572bf8a82e4663499f7f1f66c2d15a) # License [Apache License v2](http://www.apache.org/licenses/LICENSE-2.0.html) diff --git a/bin/buildDebian.sh b/bin/buildDebian.sh index cc3353c2..58431f73 100755 --- a/bin/buildDebian.sh +++ b/bin/buildDebian.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # IMPORTANT -# Protect agaisnt mispelling a var and rm -rf / +# Protect against misspelling a var and rm -rf / set -u set -e diff --git a/bin/buildForWindows.sh b/bin/buildForWindows.sh index fddb96a1..a9fbd70b 100755 --- a/bin/buildForWindows.sh +++ b/bin/buildForWindows.sh @@ -1,6 +1,6 @@ #!/bin/sh -NODE_VERSION="6.9.2" +NODE_VERSION="8.9.0" #Move to the folder where ep-lite is installed cd `dirname $0` diff --git a/bin/checkPad.js b/bin/checkPad.js index a9b7e8bc..eb45a4b4 100644 --- a/bin/checkPad.js +++ b/bin/checkPad.js @@ -10,7 +10,7 @@ if(process.argv.length != 3) //get the padID var padId = process.argv[2]; -//initalize the variables +//initialize the variables var db, settings, padManager; var npm = require("../src/node_modules/npm"); var async = require("../src/node_modules/async"); @@ -29,7 +29,7 @@ async.series([ settings = require('../src/node/utils/Settings'); db = require('../src/node/db/DB'); - //intallize the database + //initialize the database db.init(callback); }, //get the pad @@ -54,7 +54,7 @@ async.series([ }, function (callback) { - //create an array with key kevisions + //create an array with key revisions //key revisions always save the full pad atext var head = pad.getHeadRevisionNumber(); var keyRevisions = []; @@ -99,7 +99,7 @@ async.series([ process.exit(1); } - //check if there is a atext in the keyRevisions + //check if there is an atext in the keyRevisions if(revisions[keyRev] === undefined || revisions[keyRev].meta === undefined || revisions[keyRev].meta.atext === undefined) { console.error("No atext in key revision " + keyRev); diff --git a/bin/cleanRun.sh b/bin/cleanRun.sh index 55bcf8a7..ef802815 100755 --- a/bin/cleanRun.sh +++ b/bin/cleanRun.sh @@ -16,7 +16,7 @@ do fi done -#Stop the script if its started as root +#Stop the script if it's started as root if [ "$(id -u)" -eq 0 ] && [ $ignoreRoot -eq 0 ]; then echo "You shouldn't start Etherpad as root!" echo "Please type 'Etherpad rocks my socks' or supply the '--root' argument if you still want to start it as root" @@ -31,7 +31,7 @@ fi #Clean the current environment rm -rf src/node_modules -#Prepare the enviroment +#Prepare the environment bin/installDeps.sh $* || exit 1 #Move to the node folder and start diff --git a/bin/createRelease.sh b/bin/createRelease.sh index 435ec346..5afced8f 100755 --- a/bin/createRelease.sh +++ b/bin/createRelease.sh @@ -22,25 +22,25 @@ TMP_DIR="/tmp/" echo "WARNING: You can only run this script if your github api token is allowed to create and merge branches on $ETHER_REPO and $ETHER_WEB_REPO." echo "This script automatically changes the version number in package.json and adds a text to CHANGELOG.md." -echo "When you use this script you should be in the branch that you want to release (develop probably) on latest version. Any changes that are currently not commited will be commited." +echo "When you use this script you should be in the branch that you want to release (develop probably) on latest version. Any changes that are currently not committed will be committed." echo "-----" -# get the latest version +# Get the latest version LATEST_GIT_TAG=$(git tag | tail -n 1) -# current environment +# Current environment echo "Current environment: " echo "- branch: $(git branch | grep '* ')" echo "- last commit date: $(git show --quiet --pretty=format:%ad)" echo "- current version: $LATEST_GIT_TAG" echo "- temp dir: $TMP_DIR" -# get new version number +# Get new version number # format: x.x.x echo -n "Enter new version (x.x.x): " read VERSION -# get the message for the changelogs +# Get the message for the changelogs read -p "Enter new changelog entries (press enter): " tmp=$(mktemp) "${EDITOR:-vi}" $tmp @@ -49,7 +49,7 @@ echo "$changelogText" rm $tmp if [ "$changelogText" != "" ]; then - changelogText="# $VERSION\n$changelogText" + changelogText="# $VERSION\n$changelogText" fi # get the token for the github api @@ -57,114 +57,114 @@ echo -n "Enter your github api token: " read API_TOKEN function check_api_token { - echo "Checking if github api token is valid..." - CURL_RESPONSE=$(curl --silent -i https://api.github.com/user?access_token=$API_TOKEN | iconv -f utf8) - HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/') - [[ $HTTP_STATUS != "200" ]] && echo "Aborting: Invalid github api token" && exit 1 + echo "Checking if github api token is valid..." + CURL_RESPONSE=$(curl --silent -i https://api.github.com/user?access_token=$API_TOKEN | iconv -f utf8) + HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/') + [[ $HTTP_STATUS != "200" ]] && echo "Aborting: Invalid github api token" && exit 1 } function modify_files { - # Add changelog text to first line of CHANGELOG.md - sed -i "1s/^/${changelogText}\n/" CHANGELOG.md - # Replace version number of etherpad in package.json - sed -i -r "s/(\"version\"[ ]*: \").*(\")/\1$VERSION\2/" src/package.json + # Add changelog text to first line of CHANGELOG.md + sed -i "1s/^/${changelogText}\n/" CHANGELOG.md + # Replace version number of etherpad in package.json + sed -i -r "s/(\"version\"[ ]*: \").*(\")/\1$VERSION\2/" src/package.json } function create_release_branch { - echo "Creating new release branch..." - git rev-parse --verify release/$VERSION 2>/dev/null - if [ $? == 0 ]; then - echo "Aborting: Release branch already present" - exit 1 - fi - git checkout -b release/$VERSION - [[ $? != 0 ]] && echo "Aborting: Error creating relase branch" && exit 1 - - echo "Commiting CHANGELOG.md and package.json" - git add CHANGELOG.md - git add src/package.json - git commit -m "Release version $VERSION" - - echo "Pushing release branch to github..." - git push -u $ETHER_REPO release/$VERSION - [[ $? != 0 ]] && echo "Aborting: Error pushing release branch to github" && exit 1 + echo "Creating new release branch..." + git rev-parse --verify release/$VERSION 2>/dev/null + if [ $? == 0 ]; then + echo "Aborting: Release branch already present" + exit 1 + fi + git checkout -b release/$VERSION + [[ $? != 0 ]] && echo "Aborting: Error creating release branch" && exit 1 + + echo "Committing CHANGELOG.md and package.json" + git add CHANGELOG.md + git add src/package.json + git commit -m "Release version $VERSION" + + echo "Pushing release branch to github..." + git push -u $ETHER_REPO release/$VERSION + [[ $? != 0 ]] && echo "Aborting: Error pushing release branch to github" && exit 1 } function merge_release_branch { - echo "Merging release to master branch on github..." - API_JSON=$(printf '{"base": "master","head": "release/%s","commit_message": "Merge new release into master branch!"}' $VERSION) - CURL_RESPONSE=$(curl --silent -i -N --data "$API_JSON" https://api.github.com/repos/ether/etherpad-lite/merges?access_token=$API_TOKEN | iconv -f utf8) - echo $CURL_RESPONSE - HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/') - [[ $HTTP_STATUS != "200" ]] && echo "Aborting: Error merging release branch on github" && exit 1 + echo "Merging release to master branch on github..." + API_JSON=$(printf '{"base": "master","head": "release/%s","commit_message": "Merge new release into master branch!"}' $VERSION) + CURL_RESPONSE=$(curl --silent -i -N --data "$API_JSON" https://api.github.com/repos/ether/etherpad-lite/merges?access_token=$API_TOKEN | iconv -f utf8) + echo $CURL_RESPONSE + HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/') + [[ $HTTP_STATUS != "200" ]] && echo "Aborting: Error merging release branch on github" && exit 1 } function create_builds { - echo "Cloning etherpad-lite repo and ether.github.com repo..." - cd $TMP_DIR - rm -rf etherpad-lite ether.github.com - git clone $ETHER_REPO --branch master - git clone $ETHER_WEB_REPO - echo "Creating windows build..." - cd etherpad-lite - bin/buildForWindows.sh - [[ $? != 0 ]] && echo "Aborting: Error creating build for windows" && exit 1 - echo "Creating docs..." - make docs - [[ $? != 0 ]] && echo "Aborting: Error generating docs" && exit 1 + echo "Cloning etherpad-lite repo and ether.github.com repo..." + cd $TMP_DIR + rm -rf etherpad-lite ether.github.com + git clone $ETHER_REPO --branch master + git clone $ETHER_WEB_REPO + echo "Creating windows build..." + cd etherpad-lite + bin/buildForWindows.sh + [[ $? != 0 ]] && echo "Aborting: Error creating build for windows" && exit 1 + echo "Creating docs..." + make docs + [[ $? != 0 ]] && echo "Aborting: Error generating docs" && exit 1 } function push_builds { - cd $TMP_DIR/etherpad-lite/ - echo "Copying windows build and docs to website repo..." - GIT_SHA=$(git rev-parse HEAD | cut -c1-10) - mv etherpad-lite-win.zip $TMP_DIR/ether.github.com/downloads/etherpad-lite-win-$VERSION-$GIT_SHA.zip - - mv out/doc $TMP_DIR/ether.github.com/doc/v$VERSION - - cd $TMP_DIR/ether.github.com/ - sed -i "s/etherpad-lite-win.*\.zip/etherpad-lite-win-$VERSION-$GIT_SHA.zip/" index.html - sed -i "s/$LATEST_GIT_TAG/$VERSION/g" index.html - git checkout -b release_$VERSION - [[ $? != 0 ]] && echo "Aborting: Error creating new release branch" && exit 1 - git add doc/ - git add downloads/ - git commit -a -m "Release version $VERSION" - git push -u $ETHER_WEB_REPO release_$VERSION - [[ $? != 0 ]] && echo "Aborting: Error pushing release branch to github" && exit 1 + cd $TMP_DIR/etherpad-lite/ + echo "Copying windows build and docs to website repo..." + GIT_SHA=$(git rev-parse HEAD | cut -c1-10) + mv etherpad-lite-win.zip $TMP_DIR/ether.github.com/downloads/etherpad-lite-win-$VERSION-$GIT_SHA.zip + + mv out/doc $TMP_DIR/ether.github.com/doc/v$VERSION + + cd $TMP_DIR/ether.github.com/ + sed -i "s/etherpad-lite-win.*\.zip/etherpad-lite-win-$VERSION-$GIT_SHA.zip/" index.html + sed -i "s/$LATEST_GIT_TAG/$VERSION/g" index.html + git checkout -b release_$VERSION + [[ $? != 0 ]] && echo "Aborting: Error creating new release branch" && exit 1 + git add doc/ + git add downloads/ + git commit -a -m "Release version $VERSION" + git push -u $ETHER_WEB_REPO release_$VERSION + [[ $? != 0 ]] && echo "Aborting: Error pushing release branch to github" && exit 1 } function merge_web_branch { echo "Merging release to master branch on github..." API_JSON=$(printf '{"base": "master","head": "release_%s","commit_message": "Release version %s"}' $VERSION $VERSION) - CURL_RESPONSE=$(curl --silent -i -N --data "$API_JSON" https://api.github.com/repos/ether/ether.github.com/merges?access_token=$API_TOKEN | iconv -f utf8) - echo $CURL_RESPONSE - HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/') - [[ $HTTP_STATUS != "200" ]] && echo "Aborting: Error merging release branch" && exit 1 + CURL_RESPONSE=$(curl --silent -i -N --data "$API_JSON" https://api.github.com/repos/ether/ether.github.com/merges?access_token=$API_TOKEN | iconv -f utf8) + echo $CURL_RESPONSE + HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/') + [[ $HTTP_STATUS != "200" ]] && echo "Aborting: Error merging release branch" && exit 1 } function publish_release { - echo -n "Do you want to publish a new release on github (y/n)? " - read PUBLISH_RELEASE - if [ $PUBLISH_RELEASE = "y" ]; then - # create a new release on github - API_JSON=$(printf '{"tag_name": "%s","target_commitish": "master","name": "Release %s","body": "%s","draft": false,"prerelease": false}' $VERSION $VERSION $changelogText) - CURL_RESPONSE=$(curl --silent -i -N --data "$API_JSON" https://api.github.com/repos/ether/etherpad-lite/releases?access_token=$API_TOKEN | iconv -f utf8) - HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/') - [[ $HTTP_STATUS != "201" ]] && echo "Aborting: Error publishing release on github" && exit 1 - else - echo "No release published on github!" - fi + echo -n "Do you want to publish a new release on github (y/n)? " + read PUBLISH_RELEASE + if [ $PUBLISH_RELEASE = "y" ]; then + # create a new release on github + API_JSON=$(printf '{"tag_name": "%s","target_commitish": "master","name": "Release %s","body": "%s","draft": false,"prerelease": false}' $VERSION $VERSION $changelogText) + CURL_RESPONSE=$(curl --silent -i -N --data "$API_JSON" https://api.github.com/repos/ether/etherpad-lite/releases?access_token=$API_TOKEN | iconv -f utf8) + HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/') + [[ $HTTP_STATUS != "201" ]] && echo "Aborting: Error publishing release on github" && exit 1 + else + echo "No release published on github!" + fi } function todo_notification { - echo "Release procedure was successful, but you have to do some steps manually:" - echo "- Update the wiki at https://github.com/ether/etherpad-lite/wiki" - echo "- Create a pull request on github to merge the master branch back to develop" - echo "- Announce the new release on the mailing list, blog.etherpad.org and Twitter" + echo "Release procedure was successful, but you have to do some steps manually:" + echo "- Update the wiki at https://github.com/ether/etherpad-lite/wiki" + echo "- Create a pull request on github to merge the master branch back to develop" + echo "- Announce the new release on the mailing list, blog.etherpad.org and Twitter" } -# call functions +# Call functions check_api_token modify_files create_release_branch diff --git a/bin/debugRun.sh b/bin/debugRun.sh index f90009d0..b42112f7 100755 --- a/bin/debugRun.sh +++ b/bin/debugRun.sh @@ -8,7 +8,7 @@ if [ -d "../bin" ]; then cd "../" fi -#prepare the enviroment +#Prepare the environment bin/installDeps.sh || exit 1 hash node-inspector > /dev/null 2>&1 || { @@ -20,9 +20,9 @@ hash node-inspector > /dev/null 2>&1 || { node-inspector & -echo "If you are new to node-inspector, take a look at this video: http://youtu.be/AOnK3NVnxL8" +echo "If you are new to node-inspector, take a look at this video: https://youtu.be/AOnK3NVnxL8" node --debug node_modules/ep_etherpad-lite/node/server.js $* -#kill node-inspector before ending +#Kill node-inspector before ending kill $! diff --git a/bin/deletePad.js b/bin/deletePad.js index f7a6d203..fe7761db 100644 --- a/bin/deletePad.js +++ b/bin/deletePad.js @@ -37,12 +37,12 @@ async.series([ db = require('../src/node/db/DB'); callback(); }, - // intallize the database + // initialize the database function (callback) { db.init(callback); }, - // delete the pad and it's links + // delete the pad and its links function (callback) { padManager = require('../src/node/db/PadManager'); diff --git a/bin/doc/README.md b/bin/doc/README.md index 3646e46e..4646c200 100644 --- a/bin/doc/README.md +++ b/bin/doc/README.md @@ -72,5 +72,5 @@ Each type of heading has a description block. Run the following from the etherpad-lite root directory: ```sh -$ node tools/doc/generate doc/index.md --format=html --template=doc/template.html > out.html +$ node bin/doc/generate doc/index.md --format=html --template=doc/template.html > out.html ```
\ No newline at end of file diff --git a/bin/doc/json.js b/bin/doc/json.js index 2459bc26..a404675b 100644 --- a/bin/doc/json.js +++ b/bin/doc/json.js @@ -96,7 +96,7 @@ function doJSON(input, filename, cb) { // a list: starting with list_start, ending with list_end, // maybe containing other nested lists in each item. // - // If one of these isnt' found, then anything that comes between + // If one of these isn't found, then anything that comes between // here and the next heading should be parsed as the desc. var stability if (state === 'AFTERHEADING') { @@ -198,7 +198,7 @@ function processList(section) { var current; var stack = []; - // for now, *just* build the heirarchical list + // for now, *just* build the hierarchical list list.forEach(function(tok) { var type = tok.type; if (type === 'space') return; diff --git a/bin/extractPadData.js b/bin/extractPadData.js index e3678c4e..41908249 100644 --- a/bin/extractPadData.js +++ b/bin/extractPadData.js @@ -1,5 +1,5 @@ /* - This is a debug tool. It helps to extract all datas of a pad and move it from an productive enviroment and to a develop enviroment to reproduce bugs there. It outputs a dirtydb file + This is a debug tool. It helps to extract all datas of a pad and move it from an productive environment and to a develop environment to reproduce bugs there. It outputs a dirtydb file */ if(process.argv.length != 3) @@ -38,7 +38,7 @@ async.series([ dirty = require("../node_modules/ep_etherpad-lite/node_modules/ueberDB/node_modules/dirty")(padId + ".db"); callback(); }, - //intallize the database + //initialize the database function (callback) { db.init(callback); @@ -85,7 +85,7 @@ async.series([ if(err) { callback(err); return} if(dbvalue && typeof dbvalue != 'object'){ - dbvalue=JSON.parse(dbvalue); // if its not json then parse it as json + dbvalue=JSON.parse(dbvalue); // if it's not json then parse it as json } dirty.set(dbkey, dbvalue, callback); @@ -105,5 +105,5 @@ async.series([ //get the pad object //get all revisions of this pad //get all authors related to this pad -//get the readonly link releated to this pad -//get the chat entrys releated to this pad +//get the readonly link related to this pad +//get the chat entries related to this pad diff --git a/bin/importSqlFile.js b/bin/importSqlFile.js index 6491cbea..5cdf46e5 100644 --- a/bin/importSqlFile.js +++ b/bin/importSqlFile.js @@ -30,7 +30,7 @@ require("ep_etherpad-lite/node_modules/npm").load({}, function(er,npm) { //there was an error while initializing the database, output it and stop if(err) { - console.error("ERROR: Problem while initalizing the database"); + console.error("ERROR: Problem while initializing the database"); console.error(err.stack ? err.stack : err); process.exit(1); } diff --git a/bin/installDeps.sh b/bin/installDeps.sh index 48a34905..5ccba46d 100755 --- a/bin/installDeps.sh +++ b/bin/installDeps.sh @@ -23,19 +23,19 @@ hash curl > /dev/null 2>&1 || { } #Is node installed? -#not checking io.js, default installation creates a symbolic link to node +#Not checking io.js, default installation creates a symbolic link to node hash node > /dev/null 2>&1 || { - echo "Please install node.js ( http://nodejs.org )" >&2 + echo "Please install node.js ( https://nodejs.org )" >&2 exit 1 } #Is npm installed? hash npm > /dev/null 2>&1 || { - echo "Please install npm ( http://npmjs.org )" >&2 + echo "Please install npm ( https://npmjs.org )" >&2 exit 1 } -#check npm version +#Check npm version NPM_VERSION=$(npm --version) NPM_MAIN_VERSION=$(echo $NPM_VERSION | cut -d "." -f 1) if [ $(echo $NPM_MAIN_VERSION) = "0" ]; then @@ -43,7 +43,7 @@ if [ $(echo $NPM_MAIN_VERSION) = "0" ]; then exit 1 fi -#check node version +#Check node version NODE_VERSION=$(node --version) NODE_V_MINOR=$(echo $NODE_VERSION | cut -d "." -f 1-2) NODE_V_MAIN=$(echo $NODE_VERSION | cut -d "." -f 1) @@ -61,7 +61,7 @@ for arg in $*; do a=$arg done -#Does a $settings exist? if no copy the template +#Does a $settings exist? if not copy the template if [ ! -f $settings ]; then echo "Copy the settings template to $settings..." cp settings.json.template $settings || exit 1 diff --git a/bin/installOnWindows.bat b/bin/installOnWindows.bat index 89fa335d..db679ef0 100644 --- a/bin/installOnWindows.bat +++ b/bin/installOnWindows.bat @@ -1,10 +1,10 @@ @echo off -:: change directory to etherpad-lite root +:: Change directory to etherpad-lite root cd /D "%~dp0\.." :: Is node installed? -cmd /C node -e "" || ( echo "Please install node.js ( http://nodejs.org )" && exit /B 1 ) +cmd /C node -e "" || ( echo "Please install node.js ( https://nodejs.org )" && exit /B 1 ) echo _ echo Ensure that all dependencies are up to date... If this is the first time you have run Etherpad please be patient. diff --git a/bin/repairPad.js b/bin/repairPad.js index 4a90812c..28f28cb6 100644 --- a/bin/repairPad.js +++ b/bin/repairPad.js @@ -39,7 +39,7 @@ async.series([ db = require('../src/node/db/DB'); callback(); }, - //intallize the database + //initialize the database function (callback) { db.init(callback); @@ -101,6 +101,6 @@ async.series([ //get the pad object //get all revisions of this pad //get all authors related to this pad -//get the readonly link releated to this pad -//get the chat entrys releated to this pad +//get the readonly link related to this pad +//get the chat entries related to this pad //remove all keys from database and insert them again @@ -16,19 +16,19 @@ do fi done -#Stop the script if its started as root +#Stop the script if it's started as root if [ "$(id -u)" -eq 0 ] && [ $ignoreRoot -eq 0 ]; then - echo "You shouldn't start Etherpad as root!" - echo "Please type 'Etherpad rocks my socks' or supply the '--root' argument if you still want to start it as root" - read rocks - if [ ! "$rocks" == "Etherpad rocks my socks" ] - then - echo "Your input was incorrect" - exit 1 - fi + echo "You shouldn't start Etherpad as root!" + echo "Please type 'Etherpad rocks my socks' or supply the '--root' argument if you still want to start it as root" + read rocks + if [ ! "$rocks" == "Etherpad rocks my socks" ] + then + echo "Your input was incorrect" + exit 1 + fi fi -#prepare the enviroment +#Prepare the environment bin/installDeps.sh $* || exit 1 #Move to the node folder and start diff --git a/bin/safeRun.sh b/bin/safeRun.sh index 519a0b6e..d024f0b2 100755 --- a/bin/safeRun.sh +++ b/bin/safeRun.sh @@ -6,10 +6,10 @@ # 0 silent # 1 email ERROR_HANDLING=0 -# Your email address which should recieve the error messages +# Your email address which should receive the error messages EMAIL_ADDRESS="no-reply@example.com" -# Sets the minimun amount of time betweens the sending of error emails. -# This ensures you not get spamed while a endless reboot loop +# Sets the minimum amount of time between the sending of error emails. +# This ensures you do not get spammed during an endless reboot loop # It's the time in seconds TIME_BETWEEN_EMAILS=600 # 10 minutes @@ -26,7 +26,7 @@ if [ -d "../bin" ]; then cd "../" fi -#check if a logfile parameter is set +#Check if a logfile parameter is set if [ -z "${LOG}" ]; then echo "Set a logfile as the first parameter" exit 1 @@ -35,18 +35,18 @@ fi shift while [ 1 ] do - #try to touch the file if it doesn't exist + #Try to touch the file if it doesn't exist if [ ! -f ${LOG} ]; then touch ${LOG} || ( echo "Logfile '${LOG}' is not writeable" && exit 1 ) fi - #check if the file is writeable + #Check if the file is writeable if [ ! -w ${LOG} ]; then echo "Logfile '${LOG}' is not writeable" exit 1 fi - #start the application + #Start the application bin/run.sh $@ >>${LOG} 2>>${LOG} #Send email diff --git a/doc/api/changeset_library.md b/doc/api/changeset_library.md index 2dce55aa..3bb4f055 100644 --- a/doc/api/changeset_library.md +++ b/doc/api/changeset_library.md @@ -4,15 +4,15 @@ "Z:z>1|2=m=b*0|1+1$\n" ``` -This is a Changeset. Its just a string and its very difficult to read in this form. But the Changeset Library gives us some tools to read it. +This is a Changeset. It's just a string and it's very difficult to read in this form. But the Changeset Library gives us some tools to read it. -A changeset describes the diff between two revisions of the document. The Browser sends changesets to the server and the server sends them to the clients to update them. This Changesets gets also saved into the history of a pad. Which allows us to go back to every revision from the past. +A changeset describes the diff between two revisions of the document. The Browser sends changesets to the server and the server sends them to the clients to update them. These Changesets also get saved into the history of a pad. This allows us to go back to every revision from the past. ## Changeset.unpack(changeset) * `changeset` {String} -This functions returns an object representaion of the changeset, similar to this: +This function returns an object representation of the changeset, similar to this: ``` { oldLen: 35, newLen: 36, ops: '|2=m=b*0|1+1', charBank: '\n' } @@ -65,7 +65,7 @@ There are 3 types of operators: `+`,`-` and `=`. These operators describe differ fromJsonable: [Function] } ``` -This creates an empty apool. A apool saves which attributes were used during the history of a pad. There is one apool for each pad. It only saves the attributes that were really used, it doesn't save unused attributes. Lets fill this apool with some values +This creates an empty apool. An apool saves which attributes were used during the history of a pad. There is one apool for each pad. It only saves the attributes that were really used, it doesn't save unused attributes. Let's fill this apool with some values ``` > apool.fromJsonable({"numToAttrib":{"0":["author","a.kVnWeomPADAT2pn9"],"1":["bold","true"],"2":["italic","true"]},"nextNum":3}); @@ -88,7 +88,7 @@ This creates an empty apool. A apool saves which attributes were used during the fromJsonable: [Function] } ``` -We used the fromJsonable function to fill the empty apool with values. the fromJsonable and toJsonable functions are used to serialize and deserialize an apool. You can see that it stores the relation between numbers and attributes. So for example the attribute 1 is the attribute bold and vise versa. A attribute is always a key value pair. For stuff like bold and italic its just 'italic':'true'. For authors its author:$AUTHORID. So a character can be bold and italic. But it can't belong to multiple authors +We used the fromJsonable function to fill the empty apool with values. the fromJsonable and toJsonable functions are used to serialize and deserialize an apool. You can see that it stores the relation between numbers and attributes. So for example the attribute 1 is the attribute bold and vise versa. An attribute is always a key value pair. For stuff like bold and italic it's just 'italic':'true'. For authors it's author:$AUTHORID. So a character can be bold and italic. But it can't belong to multiple authors ``` > apool.getAttrib(1) diff --git a/doc/api/editbar.md b/doc/api/editbar.md index d4ad4c64..d297eb25 100644 --- a/doc/api/editbar.md +++ b/doc/api/editbar.md @@ -1,5 +1,5 @@ # Editbar -srf/static/js/pad_editbar.js +src/static/js/pad_editbar.js ## isEnabled() @@ -25,4 +25,4 @@ toolbar.registerAceCommand("insertorderedlist", function (cmd, ace) { Ties a `div.popup` where `id` equals `dropdown` to a `command` fired by clicking a button. ## triggerCommand(cmd[, item]) -Triggers a command (optionally with some internal representation of the toolbar item that triggered it).
\ No newline at end of file +Triggers a command (optionally with some internal representation of the toolbar item that triggered it). diff --git a/doc/api/editorInfo.md b/doc/api/editorInfo.md index afb790b9..7cbe3fcd 100644 --- a/doc/api/editorInfo.md +++ b/doc/api/editorInfo.md @@ -69,9 +69,9 @@ This function replaces a range (from y1 to y2) with `newText`. ## editorInfo.ace_renumberList(lineNum) If you delete a line, calling this method will fix the line numbering. ## editorInfo.ace_doReturnKey() -Forces a return key at the current carret position. +Forces a return key at the current caret position. ## editorInfo.ace_isBlockElement(element) -Returns true if your passed elment is registered as a block element +Returns true if your passed element is registered as a block element ## editorInfo.ace_getLineListType(lineNum) Returns the line's html list type. ## editorInfo.ace_caretLine() diff --git a/doc/api/embed_parameters.md b/doc/api/embed_parameters.md index dcbe3e5b..ea225d84 100644 --- a/doc/api/embed_parameters.md +++ b/doc/api/embed_parameters.md @@ -1,5 +1,5 @@ # Embed parameters -You can easily embed your etherpad-lite into any webpage by using iframes. You can configure the embedded pad using embed paramters. +You can easily embed your etherpad-lite into any webpage by using iframes. You can configure the embedded pad using embed parameters. Example: diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index 5775c49d..5dc8f094 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -36,7 +36,7 @@ Things in context: None This function is called after a specific plugin is initialized. This would probably be more useful than the previous two functions if you only wanted to add in features to one specific plugin. ## expressConfigure -Called from: src/node/server.js +Called from: src/node/hooks/express.js Things in context: @@ -45,7 +45,7 @@ Things in context: This is a helpful hook for changing the behavior and configuration of the application. It's called right after the application gets configured. ## expressCreateServer -Called from: src/node/server.js +Called from: src/node/hooks/express.js Things in context: @@ -72,7 +72,7 @@ Available blocks in `pad.html` are: * `editbarMenuRight` - right tool bar * `afterEditbar` - allows you to add stuff immediately after the toolbar * `userlist` - the contents of the userlist dropdown - * `loading` - the intial loading message + * `loading` - the initial loading message * `mySettings` - the left column of the settings dropdown ("My view"); intended for adding checkboxes only * `mySettings.dropdowns` - add your dropdown settings here * `globalSettings` - the right column of the settings dropdown ("Global view") @@ -104,9 +104,9 @@ Things in context: Here you can add custom toolbar items that will be available in the toolbar config in `settings.json`. For more about the toolbar controller see the API section. -Usage examples: +Usage examples: -* [https://github.com/tiblu/ep_authorship_toggle]() +* https://github.com/tiblu/ep_authorship_toggle ## padCreate Called from: src/node/db/Pad.js @@ -125,7 +125,7 @@ Things in context: 1. pad - the pad instance -This hook gets called when an pad was loaded. If a new pad was created and loaded this event will be emitted too. +This hook gets called when a pad was loaded. If a new pad was created and loaded this event will be emitted too. ## padUpdate Called from: src/node/db/Pad.js @@ -137,6 +137,20 @@ Things in context: This hook gets called when an existing pad was updated. +## padCopy +Called from: src/node/db/Pad.js + +Things in context: + +1. originalPad - the source pad instance +2. destinationID - the id of the pad copied from originalPad + +This hook gets called when an existing pad was copied. + +Usage examples: + +* https://github.com/ether/ep_comments + ## padRemove Called from: src/node/db/Pad.js @@ -146,6 +160,10 @@ Things in context: This hook gets called when an existing pad was removed/deleted. +Usage examples: + +* https://github.com/ether/ep_comments + ## socketio Called from: src/node/hooks/express/socketio.js @@ -201,7 +219,7 @@ Things in context: 1. message - the message being handled 2. client - the client object from socket.io -This hook will be called once a message arrive. If a plugin calls `callback(null)` the message will be dropped. However it is not possible to modify the message. +This hook will be called once a message arrive. If a plugin calls `callback(null)` the message will be dropped. However, it is not possible to modify the message. Plugins may also decide to implement custom behavior once a message arrives. @@ -254,7 +272,7 @@ Things in context: 1. clientVars - the basic `clientVars` built by the core 2. pad - the pad this session is about -This hook will be called once a client connects and the `clientVars` are being sent. Plugins can use this hook to give the client a initial configuriation, like the tracking-id of an external analytics-tool that is used on the client-side. You can also overwrite values from the original `clientVars`. +This hook will be called once a client connects and the `clientVars` are being sent. Plugins can use this hook to give the client an initial configuration, like the tracking-id of an external analytics-tool that is used on the client-side. You can also overwrite values from the original `clientVars`. Example: @@ -379,7 +397,7 @@ Things in context: 1. Pad object -Identical to `exportHtmlAdditionalTags`, but for tags that are stored with an specific value (not simply `true`) on the attribute pool. For example `['color', 'red']`, instead of `['bold', true]`. This hook will allow a plug-in developer to include more properties and attributes to support during HTML Export. An Array of arrays should be returned. The exported HTML will contain tags like `<span data-color="red">` for the content where attributes are `['color', 'red']`. +Identical to `exportHtmlAdditionalTags`, but for tags that are stored with a specific value (not simply `true`) on the attribute pool. For example `['color', 'red']`, instead of `['bold', true]`. This hook will allow a plug-in developer to include more properties and attributes to support during HTML Export. An Array of arrays should be returned. The exported HTML will contain tags like `<span data-color="red">` for the content where attributes are `['color', 'red']`. Example: ``` diff --git a/doc/api/http_api.md b/doc/api/http_api.md index 93a9b399..cacefb53 100644 --- a/doc/api/http_api.md +++ b/doc/api/http_api.md @@ -3,42 +3,42 @@ ## What can I do with this API? The API gives another web application control of the pads. The basic functions are -* create/delete pads +* create/delete pads * grant/forbid access to pads * get/set pad content The API is designed in a way, so you can reuse your existing user system with their permissions, and map it to Etherpad. Means: Your web application still has to do authentication, but you can tell Etherpad via the api, which visitors should get which permissions. This allows Etherpad to fit into any web application and extend it with real-time functionality. You can embed the pads via an iframe into your website. -Take a look at [HTTP API client libraries](https://github.com/ether/etherpad-lite/wiki/HTTP-API-client-libraries) to see if a library in your favorite language. +Take a look at [HTTP API client libraries](https://github.com/ether/etherpad-lite/wiki/HTTP-API-client-libraries) to check if a library in your favorite programming language is available. ## Examples ### Example 1 -A portal (such as WordPress) wants to give a user access to a new pad. Let's assume the user have the internal id 7 and his name is michael. +A portal (such as WordPress) wants to give a user access to a new pad. Let's assume the user have the internal id 7 and his name is michael. -Portal maps the internal userid to an etherpad author. +Portal maps the internal userid to an etherpad author. > Request: `http://pad.domain/api/1/createAuthorIfNotExistsFor?apikey=secret&name=Michael&authorMapper=7` -> +> > Response: `{code: 0, message:"ok", data: {authorID: "a.s8oes9dhwrvt0zif"}}` Portal maps the internal userid to an etherpad group: > Request: `http://pad.domain/api/1/createGroupIfNotExistsFor?apikey=secret&groupMapper=7` -> +> > Response: `{code: 0, message:"ok", data: {groupID: "g.s8oes9dhwrvt0zif"}}` Portal creates a pad in the userGroup > Request: `http://pad.domain/api/1/createGroupPad?apikey=secret&groupID=g.s8oes9dhwrvt0zif&padName=samplePad&text=This is the first sentence in the pad` -> +> > Response: `{code: 0, message:"ok", data: null}` Portal starts the session for the user on the group: > Request: `http://pad.domain/api/1/createSession?apikey=secret&groupID=g.s8oes9dhwrvt0zif&authorID=a.s8oes9dhwrvt0zif&validUntil=1312201246` -> +> > Response: `{"data":{"sessionID": "s.s8oes9dhwrvt0zif"}}` Portal places the cookie "sessionID" with the given value on the client and creates an iframe including the pad. @@ -50,7 +50,7 @@ A portal (such as WordPress) wants to transform the contents of a pad that multi Portal retrieves the contents of the pad for entry into the db as a blog post: > Request: `http://pad.domain/api/1/getText?apikey=secret&padID=g.s8oes9dhwrvt0zif$123` -> +> > Response: `{code: 0, message:"ok", data: {text:"Welcome Text"}}` Portal submits content into new blog post @@ -86,35 +86,35 @@ Responses are valid JSON in the following format: * **2** internal error * **3** no such function * **4** no or wrong API Key -* **message** a status message. Its ok if everything is fine, else it contains an error message +* **message** a status message. It's ok if everything is fine, else it contains an error message * **data** the payload ### Overview -![API Overview](http://i.imgur.com/d0nWp.png) +![API Overview](https://i.imgur.com/d0nWp.png) ## Data Types * **groupID** a string, the unique id of a group. Format is g.16RANDOMCHARS, for example g.s8oes9dhwrvt0zif * **sessionID** a string, the unique id of a session. Format is s.16RANDOMCHARS, for example s.s8oes9dhwrvt0zif * **authorID** a string, the unique id of an author. Format is a.16RANDOMCHARS, for example a.s8oes9dhwrvt0zif -* **readOnlyID** a string, the unique id of an readonly relation to a pad. Format is r.16RANDOMCHARS, for example r.s8oes9dhwrvt0zif +* **readOnlyID** a string, the unique id of a readonly relation to a pad. Format is r.16RANDOMCHARS, for example r.s8oes9dhwrvt0zif * **padID** a string, format is GROUPID$PADNAME, for example the pad test of group g.s8oes9dhwrvt0zif has padID g.s8oes9dhwrvt0zif$test ### Authentication -Authentication works via a token that is sent with each request as a post parameter. There is a single token per Etherpad deployment. This token will be random string, generated by Etherpad at the first start. It will be saved in APIKEY.txt in the root folder of Etherpad. Only Etherpad and the requesting application knows this key. Token management will not be exposed through this API. +Authentication works via a token that is sent with each request as a post parameter. There is a single token per Etherpad deployment. This token will be random string, generated by Etherpad at the first start. It will be saved in APIKEY.txt in the root folder of Etherpad. Only Etherpad and the requesting application knows this key. Token management will not be exposed through this API. ### Node Interoperability -All functions will also be available through a node module accessable from other node.js applications. +All functions will also be available through a node module accessible from other node.js applications. ### JSONP The API provides _JSONP_ support to allow requests from a server in a different domain. Simply add `&jsonp=?` to the API call. -Example usage: http://api.jquery.com/jQuery.getJSON/ +Example usage: https://api.jquery.com/jQuery.getJSON/ ## API Methods @@ -123,7 +123,7 @@ Pads can belong to a group. The padID of grouppads is starting with a groupID li #### createGroup() * API >= 1 - + creates a new group *Example returns:* @@ -132,7 +132,7 @@ creates a new group #### createGroupIfNotExistsFor(groupMapper) * API >= 1 -this functions helps you to map your application group ids to Etherpad group ids +this functions helps you to map your application group ids to Etherpad group ids *Example returns:* * `{code: 0, message:"ok", data: {groupID: g.s8oes9dhwrvt0zif}}` @@ -175,7 +175,7 @@ lists all existing groups * `{code: 0, message:"ok", data: {groupIDs: []}}` ### Author -These authors are bound to the attributes the users choose (color and name). +These authors are bound to the attributes the users choose (color and name). #### createAuthor([name]) * API >= 1 @@ -188,7 +188,7 @@ creates a new author #### createAuthorIfNotExistsFor(authorMapper [, name]) * API >= 1 -this functions helps you to map your application author ids to Etherpad author ids +this functions helps you to map your application author ids to Etherpad author ids *Example returns:* * `{code: 0, message:"ok", data: {authorID: "a.s8oes9dhwrvt0zif"}}` @@ -213,7 +213,7 @@ Returns the Author Name of the author -> can't be deleted cause this would involve scanning all the pads where this author was ### Session -Sessions can be created between a group and an author. This allows an author to access more than one group. The sessionID will be set as a cookie to the client and is valid until a certain date. The session cookie can also contain multiple comma-seperated sessionIDs, allowing a user to edit pads in different groups at the same time. Only users with a valid session for this group, can access group pads. You can create a session after you authenticated the user at your web application, to give them access to the pads. You should save the sessionID of this session and delete it after the user logged out. +Sessions can be created between a group and an author. This allows an author to access more than one group. The sessionID will be set as a cookie to the client and is valid until a certain date. The session cookie can also contain multiple comma-separated sessionIDs, allowing a user to edit pads in different groups at the same time. Only users with a valid session for this group, can access group pads. You can create a session after you authenticated the user at your web application, to give them access to the pads. You should save the sessionID of this session and delete it after the user logged out. #### createSession(groupID, authorID, validUntil) * API >= 1 @@ -307,7 +307,7 @@ returns the text of a pad formatted as HTML #### setHTML(padID, html) * API >= 1 -sets the text of a pad based on HTML, HTML must be well formed. Malformed HTML will send a warning to the API log. +sets the text of a pad based on HTML, HTML must be well-formed. Malformed HTML will send a warning to the API log. *Example returns:* * `{code: 0, message:"ok", data: null}` @@ -411,7 +411,7 @@ creates a chat message, saves it to the database and sends it to all connected c * `{code: 1, message:"text is no string", data: null}` ### Pad -Group pads are normal pads, but with the name schema GROUPID$PADNAME. A security manager controls access of them and its forbidden for normal pads to include a $ in the name. +Group pads are normal pads, but with the name schema GROUPID$PADNAME. A security manager controls access of them and it's forbidden for normal pads to include a $ in the name. #### createPad(padID [, text]) * API >= 1 @@ -543,7 +543,7 @@ return true of false #### setPassword(padID, password) * API >= 1 -returns ok or a error message +returns ok or an error message *Example returns:* * `{code: 0, message:"ok", data: null}` @@ -575,7 +575,7 @@ returns the timestamp of the last revision of the pad *Example returns:* * `{code: 0, message:"ok", data: {lastEdited: 1340815946602}}` * `{code: 1, message:"padID does not exist", data: null}` - + #### sendClientsMessage(padID, msg) * API >= 1.1 @@ -598,7 +598,7 @@ returns ok when the current api token is valid #### listAllPads() * API >= 1.2.1 - + lists all pads on this epl instance *Example returns:* diff --git a/doc/api/pluginfw.md b/doc/api/pluginfw.md index 2189c74c..7e0499c3 100644 --- a/doc/api/pluginfw.md +++ b/doc/api/pluginfw.md @@ -3,7 +3,7 @@ ## plugins.update `require("ep_etherpad-lite/static/js/plugingfw/plugins").update()` will use npm to list all installed modules and read their ep.json files, registering the contained hooks. -A hook registration is a pairs of a hook name and a function reference (filename for require() plus function name) +A hook registration is a pair of a hook name and a function reference (filename for require() plus function name) ## hooks.callAll `require("ep_etherpad-lite/static/js/plugingfw/hooks").callAll("hook_name", {argname:value})` will call all hook functions registered for `hook_name` with `{argname:value}`. diff --git a/doc/database.md b/doc/database.md index de3e9f54..9f6126d6 100644 --- a/doc/database.md +++ b/doc/database.md @@ -6,7 +6,7 @@ A list of all existing groups (a JSON object with groupIDs as keys and `1` as values). ### pad:$PADID -Saves all informations about pads +Contains all information about pads * **atext** - the latest attributed text * **pool** - the attribute pool @@ -24,10 +24,10 @@ Saves a revision $REVNUM of pad $PADID * **changeset** - the changeset of this revision ### pad:$PADID:chat:$CHATNUM -Saves a chatentry with num $CHATNUM of pad $PADID +Saves a chat entry with num $CHATNUM of pad $PADID * **text** - the text of this chat entry -* **userId** - the autorID of this chat entry +* **userId** - the authorID of this chat entry * **time** - the timestamp of this chat entry ### pad2readonly:$PADID @@ -43,9 +43,9 @@ Information about an author * **colorID** - the colorID of this author as shown in the pad ### mapper2group:$MAPPER -Maps an external application identifier to an internal group +Maps an external application identifier to an internal group ### mapper2author:$MAPPER -Maps an external application identifier to an internal author +Maps an external application identifier to an internal author ### group:$GROUPID a group of pads diff --git a/doc/documentation.md b/doc/documentation.md index 2452ec08..307c38af 100644 --- a/doc/documentation.md +++ b/doc/documentation.md @@ -10,6 +10,6 @@ provided to event handlers are detailed in a list underneath the topic heading. Every `.html` file is generated based on the corresponding -`.markdown` file in the `doc/api/` folder in the source tree. The -documentation is generated using the `tools/doc/generate.js` program. -The HTML template is located at `doc/template.html`.
\ No newline at end of file +`.md` file in the `doc/api/` folder in the source tree. The +documentation is generated using the `bin/doc/generate.js` program. +The HTML template is located at `doc/template.html`. diff --git a/doc/easysync/easysync-full-description.tex b/doc/easysync/easysync-full-description.tex index 5ed9f29e..5c936b27 100644 --- a/doc/easysync/easysync-full-description.tex +++ b/doc/easysync/easysync-full-description.tex @@ -85,7 +85,7 @@ For any two changesets $A$, $B$ such that \item[] $A=(n_1\rightarrow n_2)[\cdots]$ \item[] $B=(n_2\rightarrow n_3)[\cdots]$ \end{itemize} -it is clear that there is a third changeset $C=(n_1\rightarrow n_3)[\cdots]$ such that applying $C$ to a document $X$ yeilds the same resulting document as does applying $A$ and then $B$. In this case, we write $AB=C$. +it is clear that there is a third changeset $C=(n_1\rightarrow n_3)[\cdots]$ such that applying $C$ to a document $X$ yields the same resulting document as does applying $A$ and then $B$. In this case, we write $AB=C$. Given the representation from Section \ref{representation}, it is straightforward to compute the composition of two changesets. @@ -93,9 +93,9 @@ Given the representation from Section \ref{representation}, it is straightforwar Now we come to realtime document editing. Suppose two different users make two different changes to the same document at the same time. It is impossible to compose these changes. For example, if we have the document $X$ of length $n$, we may have $A=(n\rightarrow n_a)[\ldots n_a \mathrm{characters}]$, $B=(n\rightarrow n_b)[\ldots n_b \mathrm{characters}]$ where $n\neq n_a\neq n_b$. -It is impossible to compute $(XA)B$ because $B$ can only be applied to a document of length $n$, and $(XA)$ has length $n_a$. Similarly, $A$ cannot be appliet to $(XB)$ because $(XB)$ has length $n_b$. +It is impossible to compute $(XA)B$ because $B$ can only be applied to a document of length $n$, and $(XA)$ has length $n_a$. Similarly, $A$ cannot be applied to $(XB)$ because $(XB)$ has length $n_b$. -This is where \emph{merging} comes in. Merging takes two changesets that apply to the same initial document (and that cannot be composed), and computes a single new changeset that presevers the intent of both changes. The merge of $A$ and $B$ is written as $m(A,B)$. For the Etherpad system to work, we require that $m(A,B)=m(B,A)$. +This is where \emph{merging} comes in. Merging takes two changesets that apply to the same initial document (and that cannot be composed), and computes a single new changeset that preserves the intent of both changes. The merge of $A$ and $B$ is written as $m(A,B)$. For the Etherpad system to work, we require that $m(A,B)=m(B,A)$. Aside from what we have said so far about merging, there are many different implementations that will lead to a workable system. We have created one implementation for text that has the following constraints. @@ -156,7 +156,7 @@ server always. (This may distinguish from prior art?) The other critical design feature of the system is that \emph{A client must always be able to edit their local copy of the document, so the user is never blocked from - typing because of waiting to to send or receive data.} + typing because of waiting to send or receive data.} \section{Client State} @@ -329,7 +329,7 @@ with: \end{enumerate} \subsection{Respond to client connect} -When a server recieves a connection request from a client, +When a server receives a connection request from a client, it receives the client's unique ID and stores that in the server's set of connected clients. It then sends the client the contents of HEADTEXT, and the corresponding diff --git a/doc/localization.md b/doc/localization.md index 15c4d59d..ba247ea3 100644 --- a/doc/localization.md +++ b/doc/localization.md @@ -1,11 +1,11 @@ # Localization -Etherpad provides a multi-language user interface, that's apart from your users' content, so users from different countries can collaborate on a single document, while still having the user interface displayed in their mother tongue. +Etherpad provides a multi-language user interface, that's apart from your users' content, so users from different countries can collaborate on a single document, while still having the user interface displayed in their mother tongue. ## Translating -We rely on http://translatewiki.net to handle the translation process for us, so if you'd like to help... +We rely on https://translatewiki.net to handle the translation process for us, so if you'd like to help... -1. sign up at http://translatewiki.net +1. Sign up at https://translatewiki.net 2. Visit our [TWN project page](https://translatewiki.net/wiki/Translating:Etherpad_lite) 3. Click on `Translate Etherpad lite interface` 4. Choose a target language, you'd like to translate our interface to, and hit `Fetch` @@ -31,7 +31,7 @@ Translations will be send back to us regularly and will eventually appear in the Each translation consists of a key (the id of the string that is to be translated) and the translated string. Terms in curly braces must not be touched but left as they are, since they represent a dynamically changing part of the string like a variable. Imagine a message welcoming a user: `Welcome, {{userName}}!` would be translated as `Ahoy, {{userName}}!` in pirate. ### Client-side -We use a `language` cookie to save your language settings if you change them. If you don't, we autodetect your locale using information from your browser. Now, that we know your preferred language this information is feeded into a very nice library called [html10n.js](https://github.com/marcelklehr/html10n.js), which loads the appropriate translations and applies them to our templates, providing translation params, pluralization, include rules and even a nice javascript API along the way. +We use a `language` cookie to save your language settings if you change them. If you don't, we autodetect your locale using information from your browser. Then, the preferred language is fed into a library called [html10n.js](https://github.com/marcelklehr/html10n.js), which loads the appropriate translations and applies them to our templates. Its features include translation params, pluralization, include rules and a nice javascript API. @@ -62,7 +62,7 @@ alert(window._('pad.chat')); ``` ### 2. Create translate files in the locales directory of your plugin -* The name of the file must be the language code of the language it contains translations for (see [supported lang codes](http://joker-x.github.com/languages4translatewiki/test/); e.g. en ? English, es ? Spanish...) +* The name of the file must be the language code of the language it contains translations for (see [supported lang codes](https://joker-x.github.com/languages4translatewiki/test/); e.g. en ? English, es ? Spanish...) * The extension of the file must be `.json` * The default language is English, so your plugin should always provide `en.json` * In order to avoid naming conflicts, your message keys should start with the name of your plugin followed by a dot (see below) @@ -79,7 +79,7 @@ alert(window._('pad.chat')); } ``` -Everytime the http server is started, it will auto-detect your messages and merge them automatically with the core messages. +Every time the http server is started, it will auto-detect your messages and merge them automatically with the core messages. ### Overwrite core messages diff --git a/doc/plugins.md b/doc/plugins.md index 76c409b1..e5b00408 100644 --- a/doc/plugins.md +++ b/doc/plugins.md @@ -1,7 +1,7 @@ # Plugins Etherpad allows you to extend its functionality with plugins. A plugin registers hooks (functions) for certain events (thus certain features) in Etherpad-lite to execute its own functionality based on these events. -Publicly available plugins can be found in the npm registry (see <http://npmjs.org>). Etherpad-lite's naming convention for plugins is to prefix your plugins with `ep_`. So, e.g. it's `ep_flubberworms`. Thus you can install plugins from npm, using `npm install ep_flubberworm` in etherpad-lite's root directory. +Publicly available plugins can be found in the npm registry (see <https://npmjs.org>). Etherpad-lite's naming convention for plugins is to prefix your plugins with `ep_`. So, e.g. it's `ep_flubberworms`. Thus you can install plugins from npm, using `npm install ep_flubberworm` in etherpad-lite's root directory. You can also browse to `http://yourEtherpadInstan.ce/admin/plugins`, which will list all installed plugins and those available on npm. It even provides functionality to search through all available plugins. @@ -17,7 +17,7 @@ ep_<plugin>/ ``` If your plugin includes client-side hooks, put them in `static/js/`. If you're adding in CSS or image files, you should put those files in `static/css/ `and `static/image/`, respectively, and templates go into `templates/`. Translations go into `locales/` -A Standard directory structure like this makes it easier to navigate through your code. That said, do note, that this is not actually *required* to make your plugin run. If you want to make use of our i18n system, you need to put your translations into `locales/`, though, in order to have them intergated. (See "Localization" for more info on how to localize your plugin) +A Standard directory structure like this makes it easier to navigate through your code. That said, do note, that this is not actually *required* to make your plugin run. If you want to make use of our i18n system, you need to put your translations into `locales/`, though, in order to have them integrated. (See "Localization" for more info on how to localize your plugin) ## Plugin definition Your plugin definition goes into `ep.json`. In this file you register your hooks, indicate the parts of your plugin and the order of execution. (A documentation of all available events to hook into can be found in chapter [hooks](#all_hooks).) @@ -41,7 +41,7 @@ A hook registration is a pairs of a hook name and a function reference (filename } ``` -Etherpad-lite will expect the part of the hook definition before the colon to be a javascript file and will try to require it. The part after the colon is expected to be a valid function identifier of that module. So, you have to export your hooks, using [`module.exports`](http://nodejs.org/docs/latest/api/modules.html#modules_modules) and register it in `ep.json` as `ep_<plugin>/path/to/<file>:FUNCTIONNAME`. +Etherpad-lite will expect the part of the hook definition before the colon to be a javascript file and will try to require it. The part after the colon is expected to be a valid function identifier of that module. So, you have to export your hooks, using [`module.exports`](https://nodejs.org/docs/latest/api/modules.html#modules_modules) and register it in `ep.json` as `ep_<plugin>/path/to/<file>:FUNCTIONNAME`. You can omit the `FUNCTIONNAME` part, if the exported function has got the same name as the hook. So `"authorize" : "ep_flubberworm/foo"` will call the function `exports.authorize` in `ep_flubberworm/foo.js` ### Client hooks and server hooks @@ -89,7 +89,7 @@ Note that it would be far more sane to use `"pre"` in almost any case, but if yo Also, note that dependencies should *also* be listed in your package.json, so they can be `npm install`'d automagically when your plugin gets installed. ## Package definition -Your plugin must also contain a [package definition file](http://npmjs.org/doc/json.html), called package.json, in the project root - this file contains various metadata relevant to your plugin, such as the name and version number, author, project hompage, contributors, a short description, etc. If you publish your plugin on npm, these metadata are used for package search etc., but it's necessary for Etherpad-lite plugins, even if you don't publish your plugin. +Your plugin must also contain a [package definition file](https://docs.npmjs.com/files/package.json), called package.json, in the project root - this file contains various metadata relevant to your plugin, such as the name and version number, author, project hompage, contributors, a short description, etc. If you publish your plugin on npm, these metadata are used for package search etc., but it's necessary for Etherpad-lite plugins, even if you don't publish your plugin. ```json { diff --git a/settings.json.template b/settings.json.template index 6af5f78a..0cb10d50 100644 --- a/settings.json.template +++ b/settings.json.template @@ -73,6 +73,32 @@ "lang": "en-gb" }, + /* Pad Shortcut Keys */ + "padShortcutEnabled" : { + "altF9" : true, /* focus on the File Menu and/or editbar */ + "altC" : true, /* focus on the Chat window */ + "cmdShift2" : true, /* shows a gritter popup showing a line author */ + "delete" : true, + "return" : true, + "esc" : true, /* in mozilla versions 14-19 avoid reconnecting pad */ + "cmdS" : true, /* save a revision */ + "tab" : true, /* indent */ + "cmdZ" : true, /* undo/redo */ + "cmdY" : true, /* redo */ + "cmdI" : true, /* italic */ + "cmdB" : true, /* bold */ + "cmdU" : true, /* underline */ + "cmd5" : true, /* strike through */ + "cmdShiftL" : true, /* unordered list */ + "cmdShiftN" : true, /* ordered list */ + "cmdShift1" : true, /* ordered list */ + "cmdShiftC" : true, /* clear authorship */ + "cmdH" : true, /* backspace */ + "ctrlHome" : true, /* scroll to top of pad */ + "pageUp" : true, + "pageDown" : true + }, + /* Should we suppress errors from being visible in the default Pad Text? */ "suppressErrorsInPadText" : false, @@ -121,6 +147,10 @@ /* Privacy: disable IP logging */ "disableIPlogging" : false, + /* Time (in seconds) to automatically reconnect pad when a "Force reconnect" + message is shown to user. Set to 0 to disable automatic reconnection */ + "automaticReconnectionTimeout" : 0, + /* Users for basic authentication. is_admin = true gives access to /admin. If you do not uncomment this, /admin will not be available! */ /* diff --git a/src/locales/af.json b/src/locales/af.json index eb04e479..1a9ce4cc 100644 --- a/src/locales/af.json +++ b/src/locales/af.json @@ -1,7 +1,8 @@ { "@metadata": { "authors": [ - "Naudefj" + "Naudefj", + "Fwolff" ] }, "index.newPad": "Nuwe pad", @@ -9,13 +10,15 @@ "pad.toolbar.bold.title": "Vet (Ctrl-B)", "pad.toolbar.italic.title": "Kursief (Ctrl-I)", "pad.toolbar.underline.title": "Onderstreep (Ctrl-U)", - "pad.toolbar.strikethrough.title": "Deurgehaal", - "pad.toolbar.ol.title": "Geordende lys", - "pad.toolbar.ul.title": "Ongeordende lys", - "pad.toolbar.indent.title": "Indenteer", - "pad.toolbar.unindent.title": "Verklein indentering", + "pad.toolbar.strikethrough.title": "Deurgehaal (Ctrl+5)", + "pad.toolbar.ol.title": "Geordende lys (Ctrl+Shift+N)", + "pad.toolbar.ul.title": "Ongeordende lys (Ctrl+Shift+L)", + "pad.toolbar.indent.title": "Indenteer (TAB)", + "pad.toolbar.unindent.title": "Verklein indentering (Shift+TAB)", "pad.toolbar.undo.title": "Ongedaan maak (Ctrl-Z)", "pad.toolbar.redo.title": "Herdoen (Ctrl-Y)", + "pad.toolbar.clearAuthorship.title": "Verwyder skrywers se kleure (Ctrl+Shift+C)", + "pad.toolbar.import_export.title": "Voer in/uit van/na verskillende lêerformate", "pad.toolbar.settings.title": "Voorkeure", "pad.colorpicker.save": "Stoor", "pad.colorpicker.cancel": "Kanselleer", @@ -23,8 +26,16 @@ "pad.settings.myView": "My oorsig", "pad.settings.fontType.normal": "Normaal", "pad.settings.fontType.monospaced": "Monospasie", + "pad.settings.language": "Taal:", + "pad.importExport.import_export": "Voer in/uit", + "pad.importExport.import": "Laai enige tekslêer of dokument op", + "pad.importExport.importSuccessful": "Sukses!", "pad.importExport.exporthtml": "HTML", + "pad.importExport.exportplain": "Skoon teks", + "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", + "pad.importExport.exportopen": "ODF (Open Document-formaat)", + "pad.modals.cancel": "Kanselleer", "pad.modals.userdup.advice": "Maak weer 'n verbinding as u die venster wil gebruik.", "pad.modals.unauth": "Nie toegestaan", "pad.modals.deleted": "Geskrap.", diff --git a/src/locales/ar.json b/src/locales/ar.json index 1b9271d1..39ec236c 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -8,7 +8,9 @@ "Test Create account", "محمد أحمد عبد الفتاح", "Haytham morsy", - "ديفيد" + "ديفيد", + "Mido", + "Shbib Al-Subaie" ] }, "index.newPad": "باد جديد", @@ -63,6 +65,8 @@ "pad.modals.connected": "متصل.", "pad.modals.reconnecting": "إعادة الاتصال ببادك", "pad.modals.forcereconnect": "فرض إعادة الاتصال", + "pad.modals.reconnecttimer": "حاول إعادة الاتصال", + "pad.modals.cancel": "إلغاء", "pad.modals.userdup": "مفتوح في نافذة أخرى", "pad.modals.userdup.explanation": "يبدو أن هذا الباد تم فتحه في أكثر من نافذة متصفح في هذا الحاسوب.", "pad.modals.userdup.advice": "إعادة الاتصال لاستعمال هذه النافذة بدلاً من الأخرى.", diff --git a/src/locales/ast.json b/src/locales/ast.json index e39bf6ef..f1fd2f5e 100644 --- a/src/locales/ast.json +++ b/src/locales/ast.json @@ -56,6 +56,8 @@ "pad.modals.connected": "Coneutáu.", "pad.modals.reconnecting": "Reconeutando col to bloc...", "pad.modals.forcereconnect": "Forzar la reconexón", + "pad.modals.reconnecttimer": "Tentando reconeutar en", + "pad.modals.cancel": "Encaboxar", "pad.modals.userdup": "Abiertu n'otra ventana", "pad.modals.userdup.explanation": "Esti bloc paez que ta abiertu en más d'una ventana del navegador d'esti ordenador.", "pad.modals.userdup.advice": "Reconeutar pa usar esta ventana.", diff --git a/src/locales/az.json b/src/locales/az.json index 48f0f841..800c22e5 100644 --- a/src/locales/az.json +++ b/src/locales/az.json @@ -5,7 +5,8 @@ "Khan27", "Mushviq Abdulla", "Wertuose", - "Mastizada" + "Mastizada", + "Archaeodontosaurus" ] }, "index.newPad": "Yeni lövhə", @@ -114,6 +115,7 @@ "timeslider.month.december": "Dekabr", "timeslider.unnamedauthors": "{{num}} adsız {[plural(num) one: müəllif, other: müəllif]}", "pad.savedrevs.marked": "Bu versiya indi yaddaşa saxlanmış kimi nişanlandı", + "pad.savedrevs.timeslider": "Siz görə bilərsiniz saxlanılan versiyası miqyasında vaxt", "pad.userlist.entername": "Adınızı daxil edin", "pad.userlist.unnamed": "adsız", "pad.userlist.guest": "Qonaq", diff --git a/src/locales/azb.json b/src/locales/azb.json index f8d8f93b..4eeec317 100644 --- a/src/locales/azb.json +++ b/src/locales/azb.json @@ -59,6 +59,8 @@ "pad.modals.connected": "باغلاندی.", "pad.modals.reconnecting": "یادداشت دفترچهنیزه یئنیدن باغلانمایا چالیشیلیر...", "pad.modals.forcereconnect": "تکرار باغلانماق اوچون زوْرلاما", + "pad.modals.reconnecttimer": "یئنیدن باغلانمایا چالیشیلیر", + "pad.modals.cancel": "وازگئچ", "pad.modals.userdup": "آیری پنجره ده آچیلدی", "pad.modals.userdup.advice": "بو پئنجره دن ایستفاده ائتمک اوچون یئنی دن متصیل اول", "pad.modals.unauth": "اوْلماز", @@ -68,10 +70,14 @@ "pad.modals.initsocketfail": "سرور الده دئییلدیر.", "pad.modals.initsocketfail.explanation": "بیرلشدیریلمه سرور لرینه متصیل اولا بیلمه دی", "pad.modals.slowcommit.explanation": "سرور جواب وئرمه ییر.", + "pad.modals.slowcommit.cause": "بو، شبکه باغلانتیسیندا خطالار اوچون اولا بیلر.", + "pad.modals.corruptPad.explanation": "ال تاپماغا چالیشدیغینیز پد کورلانیبدیر.", + "pad.modals.corruptPad.cause": "بو، غلط سرور تنظیملری یوخسا آیری بیر گوزلنیلمز بیر داورانیشدان عمله گله بیلر. لوطفا سرویس ایداره چیسی ایله تماس توتون.", "pad.modals.deleted": "سیلیندی.", "pad.modals.deleted.explanation": "بۇ یادداشت دفترچهسی سیلینیبدیر.", "pad.modals.disconnected": "سیزین باغلانتینیز کسیلیبدیر.", "pad.modals.disconnected.explanation": "سروره باغلانتی کسیلیبدیر.", + "pad.modals.disconnected.cause": "سرور ال چاتماز اولا بیلر. بئله قالیرسا سرویس ایداره چیسینی آییق سالین.", "pad.share": "بو نوت دفترچه سینی پایلاش", "pad.share.readonly": "سادهجه اوْخومالی", "pad.share.link": "باغلانتی", @@ -86,6 +92,8 @@ "timeslider.toolbar.exportlink.title": "ائشیگه آپارماق", "timeslider.exportCurrent": "موجود نوسخه نی بو عونوانلا ائشیگه چیخارت:", "timeslider.version": "{{version}} ورژنی", + "timeslider.saved": "ساخلانیلدی {{day}} {{month}}, {{year}}", + "timeslider.playPause": "پد ایچیندهکیلری یئنه اوْخوت/دۇردور", "timeslider.month.january": "ژانویه", "timeslider.month.february": "فوریه", "timeslider.month.march": "مارس", @@ -98,11 +106,13 @@ "timeslider.month.october": "اوْکتوبر", "timeslider.month.november": "نوْوامبر", "timeslider.month.december": "دسامبر", + "pad.savedrevs.marked": "بۇ نوسخه ایندی ذخیره اوْلونموش کیمی علامتلندی.", "pad.userlist.entername": "آدینیزی یازین", "pad.userlist.unnamed": "آدسیز", "pad.userlist.guest": "قوْناق", "pad.userlist.deny": "دانماق", "pad.userlist.approve": "اوْنایلا", + "pad.editbar.clearcolors": "بوتون سندلرده یازار بوْیالاری سیلینسین می؟", "pad.impexp.importbutton": "ایندی ایچری گتیر", "pad.impexp.importing": "ایچری گتیریلیر...", "pad.impexp.uploadFailed": "آپلود اولونمادی، یئنه چالیشین", diff --git a/src/locales/be-tarask.json b/src/locales/be-tarask.json index 2d8c26e8..84af7315 100644 --- a/src/locales/be-tarask.json +++ b/src/locales/be-tarask.json @@ -54,10 +54,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "Вы можаце імпартаваць толькі з звычайнага тэксту або HTML. Дзеля больш пашыраных магчымасьцяў імпарту, калі ласка, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">усталюйце abiword</a>.", + "pad.importExport.abiword.innerHTML": "Вы можаце імпартаваць толькі з звычайнага тэксту або HTML. Дзеля больш пашыраных магчымасьцяў імпарту, калі ласка, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">усталюйце AbiWord</a>.", "pad.modals.connected": "Падлучыліся.", "pad.modals.reconnecting": "Перападлучэньне да вашага дакумэнта...", "pad.modals.forcereconnect": "Прымусовае перападлучэньне", + "pad.modals.reconnecttimer": "Спрабуем перападключыцца праз", + "pad.modals.cancel": "Адмяніць", "pad.modals.userdup": "Адкрыта ў іншым акне", "pad.modals.userdup.explanation": "Падобна, дакумэнт адкрыты больш чым у адным акне браўзэра на гэтым кампутары.", "pad.modals.userdup.advice": "Паўторна падключыць з выкарыстаньнем гэтага акна.", diff --git a/src/locales/bg.json b/src/locales/bg.json new file mode 100644 index 00000000..52e424c3 --- /dev/null +++ b/src/locales/bg.json @@ -0,0 +1,69 @@ +{ + "@metadata": { + "authors": [ + "Vodnokon4e", + "StanProg" + ] + }, + "index.newPad": "Нов пад", + "index.createOpenPad": "или създаване/отваряне на пад с име:", + "pad.toolbar.bold.title": "Получер (Ctrl+B)", + "pad.toolbar.italic.title": "Наклонен (Ctrl+I)", + "pad.toolbar.underline.title": "Подчертан (Ctrl+U)", + "pad.toolbar.strikethrough.title": "Зачеркнат (Ctrl+5)", + "pad.toolbar.ol.title": "Подреден списък (Ctrl+Shift+N)", + "pad.toolbar.ul.title": "Неподреден списък (Ctrl+Shift+L)", + "pad.toolbar.indent.title": "Отстъп (TAB)", + "pad.toolbar.unindent.title": "Премахване на отстъпа (Shift+TAB)", + "pad.toolbar.undo.title": "Отмяна (Ctrl+Z)", + "pad.toolbar.redo.title": "Връщане (Ctrl+Y)", + "pad.toolbar.settings.title": "Настройки", + "pad.colorpicker.save": "Съхраняване", + "pad.colorpicker.cancel": "Отказване", + "pad.loading": "Зареждане...", + "pad.wrongPassword": "Неправилна парола", + "pad.settings.language": "Език:", + "pad.importExport.exportetherpad": "Etherpad", + "pad.importExport.exporthtml": "HTML", + "pad.importExport.exportplain": "Обикновен текст", + "pad.importExport.exportword": "Microsoft Word", + "pad.importExport.exportpdf": "PDF", + "pad.importExport.exportopen": "ODF (Open Document Format)", + "pad.modals.cancel": "Отказване", + "pad.modals.userdup": "Отворен в друг прозорец", + "pad.modals.userdup.explanation": "Изглежда, че този пад е отворен на повече от един раздел в браузъра на компютъра.", + "pad.modals.looping.explanation": "Има проблеми с комуникацията със сървъра за синхронизация.", + "pad.modals.looping.cause": "Може би сте свързани чрез несъвместима защитна стена или прокси.", + "pad.modals.initsocketfail": "Сървърът е недостъпен.", + "pad.modals.initsocketfail.explanation": "Свързването със сървъра за синхронизация е неуспешно.", + "pad.modals.initsocketfail.cause": "Това вероятно се дължи на проблем с браузъра Ви или връзката Ви с Интернет.", + "pad.modals.slowcommit.explanation": "Сървърът не отговаря.", + "pad.modals.slowcommit.cause": "Това може да се дължи на проблеми с мрежовите връзки.", + "pad.modals.deleted": "Изтрито.", + "pad.share.readonly": "Само за четене", + "pad.share.link": "Препратка", + "pad.share.emebdcode": "Постави URL", + "pad.chat": "Чат", + "pad.chat.title": "Отваряне на чат за този пад.", + "pad.chat.loadmessages": "Зареждане на повече съобщения", + "timeslider.toolbar.returnbutton": "Връщане към пада", + "timeslider.toolbar.authors": "Автори:", + "timeslider.toolbar.authorsList": "Няма автори", + "timeslider.toolbar.exportlink.title": "Изнасяне", + "timeslider.exportCurrent": "Изнасяне на текущата версия като:", + "timeslider.version": "Версия {{version}}", + "timeslider.month.january": "януари", + "timeslider.month.february": "февруари", + "timeslider.month.march": "март", + "timeslider.month.april": "април", + "timeslider.month.may": "май", + "timeslider.month.june": "юни", + "timeslider.month.july": "юли", + "timeslider.month.august": "август", + "timeslider.month.september": "септември", + "timeslider.month.october": "октомври", + "timeslider.month.november": "ноември", + "timeslider.month.december": "декември", + "pad.userlist.entername": "Въведете вашето име", + "pad.userlist.guest": "Гост" +} diff --git a/src/locales/br.json b/src/locales/br.json index 6a60fa3a..aa31f7fa 100644 --- a/src/locales/br.json +++ b/src/locales/br.json @@ -59,6 +59,8 @@ "pad.modals.connected": "Kevreet.", "pad.modals.reconnecting": "Adkevreañ war-zu ho pad...", "pad.modals.forcereconnect": "Adkevreañ dre heg", + "pad.modals.reconnecttimer": "O klask adkevreañ", + "pad.modals.cancel": "Nullañ", "pad.modals.userdup": "Digor en ur prenestr all", "pad.modals.userdup.explanation": "Digor eo ho pad, war a seblant, e meur a brenestr eus ho merdeer en urzhiataer-mañ.", "pad.modals.userdup.advice": "Kevreañ en ur implijout ar prenestr-mañ.", diff --git a/src/locales/bs.json b/src/locales/bs.json new file mode 100644 index 00000000..e4fb5746 --- /dev/null +++ b/src/locales/bs.json @@ -0,0 +1,90 @@ +{ + "@metadata": { + "authors": [ + "Edinwiki", + "Srdjan m" + ] + }, + "pad.toolbar.bold.title": "Podebljano (Ctrl+B)", + "pad.toolbar.italic.title": "Ukošeno (Ctrl+I)", + "pad.toolbar.underline.title": "Podvučeno (Ctrl+U)", + "pad.toolbar.strikethrough.title": "Precrtano (Ctrl+5)", + "pad.toolbar.ol.title": "Poredani spisak (Ctrl+Shift+N)", + "pad.toolbar.ul.title": "Neporedani spisak (Ctrl+Shift+L)", + "pad.toolbar.indent.title": "Uvučeno (TAB)", + "pad.toolbar.unindent.title": "Izvučeno (Shift+TAB)", + "pad.toolbar.undo.title": "Poništi (Ctrl+Z)", + "pad.toolbar.redo.title": "Ponovi (Ctrl+Y)", + "pad.toolbar.timeslider.title": "Historijski pregled", + "pad.toolbar.settings.title": "Postavke", + "pad.colorpicker.save": "Sačuvaj", + "pad.colorpicker.cancel": "Otkaži", + "pad.loading": "Učitavam...", + "pad.noCookie": "Kolačić nije pronađen. Dozvolite kolačiće u Vašem pregledniku!", + "pad.wrongPassword": "Pogrešna lozinka", + "pad.settings.myView": "Moj prikaz", + "pad.settings.stickychat": "Ćaskanje uvijek na ekranu", + "pad.settings.chatandusers": "Prikaži ćaskanje i korisnike", + "pad.settings.linenocheck": "Brojevi redova", + "pad.settings.rtlcheck": "Da prikažem sadržaj zdesna ulijevo?", + "pad.settings.fontType": "Vrsta fonta:", + "pad.settings.fontType.normal": "Normalno", + "pad.settings.globalView": "Globalni prikaz", + "pad.settings.language": "Jezik:", + "pad.importExport.import_export": "Uvoz/Izvoz", + "pad.importExport.import": "Postavite bilo koju tekstualnu datoteku ili dokument", + "pad.importExport.importSuccessful": "Uspješno!", + "pad.importExport.exportetherpad": "Etherpad", + "pad.importExport.exporthtml": "HTML", + "pad.importExport.exportplain": "Obični tekst", + "pad.importExport.exportword": "Microsoft Word", + "pad.importExport.exportpdf": "PDF", + "pad.importExport.exportopen": "ODF (Open Document Format)", + "pad.modals.connected": "Spojeno.", + "pad.modals.forcereconnect": "Prisilno se ponovo poveži", + "pad.modals.reconnecttimer": "Pokušavam se ponovo povezati", + "pad.modals.cancel": "Otkaži", + "pad.modals.userdup": "Otvoreno u drugom prozoru", + "pad.modals.userdup.advice": "Ponovo se povežite da biste koristili ovaj prozor.", + "pad.modals.unauth": "Niste ovlašteni", + "pad.modals.initsocketfail": "Server je nedostupan.", + "pad.modals.initsocketfail.explanation": "Ne mogu se povezati sa sinhronizacijskim serverom.", + "pad.modals.slowcommit.explanation": "Server se ne odaziva.", + "pad.modals.deleted": "Obrisano.", + "pad.modals.disconnected": "Veza je prekinuta.", + "pad.modals.disconnected.explanation": "Izgubljena je veza sa serverom", + "pad.modals.disconnected.cause": "Moguće je da server nije dostupan. Obavijestite administratora ako se ovo nastavi dešavati.", + "pad.share.readonly": "Samo za čitanje", + "pad.share.link": "Link", + "pad.share.emebdcode": "URL za ugradnju", + "pad.chat": "Ćaskanje", + "pad.chat.loadmessages": "Učitaj više poruka", + "timeslider.pageTitle": "{{appTitle}} Historijski pregled", + "timeslider.toolbar.authors": "Autori:", + "timeslider.toolbar.authorsList": "Nema autora", + "timeslider.toolbar.exportlink.title": "Izvoz", + "timeslider.exportCurrent": "Izvezi trenutnu verziju kao:", + "timeslider.version": "Verzija {{version}}", + "timeslider.saved": "Sačuvano na datum {{day}}. {{month}} {{year}}", + "timeslider.month.january": "januar", + "timeslider.month.february": "februar", + "timeslider.month.march": "mart", + "timeslider.month.april": "april", + "timeslider.month.may": "maj", + "timeslider.month.june": "juni", + "timeslider.month.july": "juli", + "timeslider.month.august": "august", + "timeslider.month.september": "septembar", + "timeslider.month.october": "oktobar", + "timeslider.month.november": "novembar", + "timeslider.month.december": "decembar", + "pad.userlist.entername": "Upišite svoje ime", + "pad.userlist.unnamed": "bez imena", + "pad.userlist.guest": "Gost", + "pad.userlist.deny": "Odbij", + "pad.userlist.approve": "Odobri", + "pad.impexp.importbutton": "Uvezi odmah", + "pad.impexp.importing": "Uvozim...", + "pad.impexp.uploadFailed": "Postavljanje nije uspjelo. Pokušajte ponovo", + "pad.impexp.importfailed": "Uvoz neuspješan" +} diff --git a/src/locales/ca.json b/src/locales/ca.json index 40a833d0..71430610 100644 --- a/src/locales/ca.json +++ b/src/locales/ca.json @@ -8,7 +8,8 @@ "Macofe", "Joan manel", "Eduardo Martinez", - "Jaumeortola" + "Jaumeortola", + "Ssola" ] }, "index.newPad": "Nou pad", @@ -63,6 +64,8 @@ "pad.modals.connected": "Connectat.", "pad.modals.reconnecting": "S'està tornant a connectar al vostre pad…", "pad.modals.forcereconnect": "Força tornar a connectar", + "pad.modals.reconnecttimer": "Intentant reconnectar en", + "pad.modals.cancel": "Cancel·la", "pad.modals.userdup": "Obert en una altra finestra", "pad.modals.userdup.explanation": "Aquest pad sembla que està obert en més d'una finestra de navegador de l'ordinador.", "pad.modals.userdup.advice": "Torneu a connectar-vos per a utilitzar aquesta finestra.", diff --git a/src/locales/cs.json b/src/locales/cs.json index cc537de7..cda8ccb0 100644 --- a/src/locales/cs.json +++ b/src/locales/cs.json @@ -7,7 +7,8 @@ "Leanes", "Quinn", "Aktron", - "Mormegil" + "Mormegil", + "Dvorapa" ] }, "index.newPad": "Založ nový Pad", @@ -58,7 +59,7 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "Importovat můžeš pouze prostý text nebo HTML formátování. Pro pokročilejší funkce importu, prosím, nainstaluj „<a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">abiword</a>“.", + "pad.importExport.abiword.innerHTML": "Importovat můžeš pouze prostý text nebo HTML formátování. Pro pokročilejší funkce importu, prosím, nainstaluj „<a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">AbiWord</a>“.", "pad.modals.connected": "Připojeno.", "pad.modals.reconnecting": "Znovupřipojování k Padu…", "pad.modals.forcereconnect": "Vynutit znovupřipojení", diff --git a/src/locales/da.json b/src/locales/da.json index 662e9afb..06280b8e 100644 --- a/src/locales/da.json +++ b/src/locales/da.json @@ -3,7 +3,8 @@ "authors": [ "Christian List", "Peter Alberti", - "Steenth" + "Steenth", + "Joedalton" ] }, "index.newPad": "Ny Pad", @@ -28,12 +29,14 @@ "pad.colorpicker.save": "Gem", "pad.colorpicker.cancel": "Afbryd", "pad.loading": "Indlæser ...", + "pad.noCookie": "Cookie kunne ikke findes. Tillad venligst cookier i din browser!", "pad.passwordRequired": "Du skal bruge en adgangskode for at få adgang til denne pad", "pad.permissionDenied": "Du har ikke tilladelse til at få adgang til denne pad.", "pad.wrongPassword": "Din adgangskode er forkert", "pad.settings.padSettings": "Pad indstillinger", "pad.settings.myView": "Min visning", "pad.settings.stickychat": "Chat altid på skærmen", + "pad.settings.chatandusers": "Vis snak (chat) og brugere", "pad.settings.colorcheck": "Forfatterskabsfarver", "pad.settings.linenocheck": "Linjenumre", "pad.settings.rtlcheck": "Læse indhold fra højre mod venstre?", @@ -46,15 +49,18 @@ "pad.importExport.import": "Uploade en tekstfil eller dokument", "pad.importExport.importSuccessful": "Vellykket!", "pad.importExport.export": "Eksporter aktuelle pad som:", + "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "Almindelig tekst", "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "Du kan kun importere fra almindelig tekst eller HTML-formater. For mere avancerede importfunktioner, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">installer venligst abiword</a>.", + "pad.importExport.abiword.innerHTML": "Du kan kun importere fra almindelig tekst eller HTML-formater. For mere avancerede importfunktioner, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">installer AbiWord</a>.", "pad.modals.connected": "Forbundet.", "pad.modals.reconnecting": "Genopretter forbindelsen til din pad...", "pad.modals.forcereconnect": "Gennemtving genoprettelse af forbindelsen", + "pad.modals.reconnecttimer": "Prøver at tilkoble igen", + "pad.modals.cancel": "Afbryd", "pad.modals.userdup": "Åbnet i et andet vindue", "pad.modals.userdup.explanation": "Denne pad synes at være åbnet i mere end ét browservindue på denne computer.", "pad.modals.userdup.advice": "Tilslut igen for at bruge dette vindue i stedet.", @@ -91,6 +97,9 @@ "timeslider.exportCurrent": "Eksporter aktuelle version som:", "timeslider.version": "Version {{version}}", "timeslider.saved": "Gemt den {{day}}.{{month}} {{year}}", + "timeslider.playPause": "Afspil eller sæt padindhold på pause", + "timeslider.backRevision": "Gå en revision tilbage i denne pad", + "timeslider.forwardRevision": "Gå en revision fremad i denne pad", "timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}", "timeslider.month.january": "januar", "timeslider.month.february": "februar", @@ -106,6 +115,7 @@ "timeslider.month.december": "december", "timeslider.unnamedauthors": "{{num}} {[plural(num) one: unavngiven forfatter, other: unavngivne forfattere]}", "pad.savedrevs.marked": "Denne revision er nu markeret som en gemt revision", + "pad.savedrevs.timeslider": "Du kan se gemte revisioner ved at besøge tidslinjen", "pad.userlist.entername": "Indtast dit navn", "pad.userlist.unnamed": "ikke-navngivet", "pad.userlist.guest": "Gæst", @@ -116,6 +126,7 @@ "pad.impexp.importing": "Importerer...", "pad.impexp.confirmimport": "At importere en fil, vil overskrives den aktuelle pad tekst. Er du sikker på du vil fortsætte?", "pad.impexp.convertFailed": "Vi var ikke i stand til at importere denne fil. Brug et andet dokument-format eller kopier og sæt ind manuelt", + "pad.impexp.padHasData": "Vi kunne ikke importere denne fil, da denne pad allerede har haft ændringer; lav venligst import til en ny pad", "pad.impexp.uploadFailed": "Upload mislykkedes, prøv igen", "pad.impexp.importfailed": "Importen mislykkedes", "pad.impexp.copypaste": "Venligst kopier og sæt ind", diff --git a/src/locales/de.json b/src/locales/de.json index f32b8cf6..85bd3bff 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -58,10 +58,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "Sie können nur aus reinen Text- oder HTML-Formaten importieren. Für umfangreichere Importfunktionen <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">installieren Sie bitte abiword</a>.", + "pad.importExport.abiword.innerHTML": "Sie können nur aus reinen Text- oder HTML-Formaten importieren. Für umfangreichere Importfunktionen <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">installieren Sie bitte AbiWord</a>.", "pad.modals.connected": "Verbunden.", "pad.modals.reconnecting": "Wiederherstellen der Verbindung …", "pad.modals.forcereconnect": "Erneutes Verbinden erzwingen", + "pad.modals.reconnecttimer": "Versuche Neuverbindung in", + "pad.modals.cancel": "Abbrechen", "pad.modals.userdup": "In einem anderen Fenster geöffnet", "pad.modals.userdup.explanation": "Dieses Pad scheint in mehr als einem Browser-Fenster auf diesem Rechner geöffnet zu sein.", "pad.modals.userdup.advice": "Um stattdessen dieses Fenster zu verwenden, verbinden Sie sich bitte erneut.", diff --git a/src/locales/diq.json b/src/locales/diq.json index e1546e94..c57284ac 100644 --- a/src/locales/diq.json +++ b/src/locales/diq.json @@ -4,7 +4,9 @@ "Erdemaslancan", "Gorizon", "Mirzali", - "Kumkumuk" + "Kumkumuk", + "1917 Ekim Devrimi", + "Gırd" ] }, "index.newPad": "Pedo newe", @@ -25,7 +27,7 @@ "pad.toolbar.savedRevision.title": "Çımraviyarnayışi qeyd ke", "pad.toolbar.settings.title": "Sazkerdışi", "pad.toolbar.embed.title": "Na bloknot degusn u bıhesrne", - "pad.toolbar.showusers.title": "Na bloknot de karbera bıasne", + "pad.toolbar.showusers.title": "Karbera ena bloknot dı bımotné", "pad.colorpicker.save": "Qeyd ke", "pad.colorpicker.cancel": "Bıtexelne", "pad.loading": "Bar beno...", @@ -59,6 +61,7 @@ "pad.modals.connected": "Gırediya.", "pad.modals.reconnecting": "Bloknot da şıma rê fına irtibat kewê no", "pad.modals.forcereconnect": "Mecbur anciya gırê de", + "pad.modals.cancel": "Bıtexelne", "pad.modals.userdup": "Zewbina pençere de bi a", "pad.modals.userdup.explanation": "Ena bloknot ena komputer de yew ra zeder penceran dı akerde asena", "pad.modals.userdup.advice": "Ena pencera ra kar finayışi rê fına irtibat kewê", @@ -114,7 +117,7 @@ "timeslider.unnamedauthors": "{{num}} unnamed {[plural(num) zu: nuştoğ, zewbi: nustoği ]}", "pad.savedrevs.marked": "Eno vurriyayış henda qeyd bıyaye yew vurriyayış deyne nışan bıyo", "pad.savedrevs.timeslider": "Xızberê zemani ziyer kerdış ra şıma şenê revizyonanê qeyd bıyayan bıvinê", - "pad.userlist.entername": "Nameyê xo cıkewe", + "pad.userlist.entername": "Namey xo cıkewe", "pad.userlist.unnamed": "Name nébıyo", "pad.userlist.guest": "Meyman", "pad.userlist.deny": "Red ke", diff --git a/src/locales/dty.json b/src/locales/dty.json index c0d439e6..0682da67 100644 --- a/src/locales/dty.json +++ b/src/locales/dty.json @@ -6,8 +6,8 @@ "Nirajan pant" ] }, - "index.newPad": "नयाँ प्याड", - "index.createOpenPad": "नाम सहितको नयाँ प्याड सिर्जना गद्य्या / खोल्या :", + "index.newPad": "नौलो प्याड", + "index.createOpenPad": "नाउँ सहितको नौलो प्याड सिर्जना गद्य्या / खोल्ल्या :", "pad.toolbar.bold.title": "मोटो (Ctrl-B)", "pad.toolbar.italic.title": "ढल्के (Ctrl-I)", "pad.toolbar.underline.title": "इसो रेखाङ्कन (Ctrl-U)", @@ -16,46 +16,48 @@ "pad.toolbar.ul.title": "अक्रमाङ्कित सूची (Ctrl+Shift+L)", "pad.toolbar.indent.title": "इन्डेन्ट (TAB)", "pad.toolbar.unindent.title": "आउटडेन्ट (Shift+TAB)", - "pad.toolbar.undo.title": "खारेजी (Ctrl-Z)", + "pad.toolbar.undo.title": "अण्डू (Ctrl-Z)", "pad.toolbar.redo.title": "दोसर्या:लागु (Ctrl-Y)", "pad.toolbar.clearAuthorship.title": "लेखकीय रङ्ग हटाउन्या (Ctrl+Shift+C)", "pad.toolbar.import_export.title": "विविध फाइल फर्म्याटअन बठेइ/मी आयात/निर्यात", "pad.toolbar.timeslider.title": "टाइमस्लाइडर", - "pad.toolbar.savedRevision.title": "पुनरावलोकन संग्रहा गद्य्य", - "pad.toolbar.settings.title": "सेटिङ्गहरू", + "pad.toolbar.savedRevision.title": "पुनरावलोकन संग्रह गद्य्या", + "pad.toolbar.settings.title": "सेटिङ्गअन", "pad.toolbar.embed.title": "यै प्याडलाई बाड्न्या यात इम्बेड गद्य्या", "pad.toolbar.showusers.title": "यै प्याडमि रयाका प्रयोगकर्ता देखाउन्या", "pad.colorpicker.save": "सङ्ग्रह गद्या", "pad.colorpicker.cancel": "खारेजी", - "pad.loading": "लोड हुन्नाछ....", + "pad.loading": "लोड हुन्नाछ़....", "pad.noCookie": "कुकी पाउन नाइ सकियो। तमरा ब्राउजरमी कुकी राख्दाइ अनुमति दिय!", - "pad.passwordRequired": "यो प्यड खोल्लाकी पासवर्ड चाहिन्छ", + "pad.passwordRequired": "यो प्याड खोल्लाकी पासवर्ड चाहिन्छ", "pad.permissionDenied": "तमलाईँ यै प्याड खोल्लाकी अनुमति नाइथिन", "pad.wrongPassword": "तमरो पासवर्ड गलत थ्यो", - "pad.settings.padSettings": "प्याड सेटिङ्गहरू", + "pad.settings.padSettings": "प्याड सेटिङ्गअन", "pad.settings.myView": "मेरि हेराइ", - "pad.settings.stickychat": "पर्दामा जबलई कुरडी गद्य्या", - "pad.settings.chatandusers": "वार्ता और प्रयोगकर्ताहरू देखाउन्या", + "pad.settings.stickychat": "जबलई पर्दामी कुरडी गद्य्या", + "pad.settings.chatandusers": "वार्ता और प्रयोगकर्ताअन देखाउन्या", "pad.settings.colorcheck": "लेखकीय रङ्ग", "pad.settings.linenocheck": "हरफ संख्या", - "pad.settings.rtlcheck": "के सामग्री दाहिना बठे देब्रे पढ्न्या हो ?", + "pad.settings.rtlcheck": "सामग्री दाहिना बठे देब्रे पढ्न्या हो कि?", "pad.settings.fontType": "फन्ट प्रकार:", "pad.settings.globalView": "विश्वव्यापी दृष्य", - "pad.settings.language": "भाषा: $1", - "pad.importExport.import_export": "आउन्या/झान्या", - "pad.importExport.import": "कोइलै पाठ रयाको फाइल और कागजात अपलोड गरिदिय", + "pad.settings.language": "भाषा:", + "pad.importExport.import_export": "आयात/निर्यात", + "pad.importExport.import": "कोइलै पाठ फाइल और कागजात अपलोड अरऽ", "pad.importExport.importSuccessful": "सफल भयो!", - "pad.importExport.export": "निम्न रुपमि प्याड पठौन्या :", + "pad.importExport.export": "निम्न रुपमि प्याड निर्यात:", "pad.importExport.exportetherpad": "इथरप्याड", - "pad.importExport.exporthtml": "हटमेल", - "pad.importExport.exportplain": "सानतिनो पाठ", + "pad.importExport.exporthtml": "HTML", + "pad.importExport.exportplain": "सादा पाठ", "pad.importExport.exportword": "माइक्रोसफ्ट वर्ड", "pad.importExport.exportpdf": "पिडिएफ", - "pad.importExport.exportopen": "ओडिएफ(खुल्ला कागजात ढाँचा)", + "pad.importExport.exportopen": "ओडिएफ (खुल्ला कागजात ढाँचा)", "pad.importExport.abiword.innerHTML": "तम सादा पाठ या HTML ढाँचा बठेइ मात्तरी आयात अरीसकन्छऽ। विस्तारित आयात विशेषता खिलाई कृपया <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">abiword स्थापना अरऽ</a>।", - "pad.modals.connected": "जोडीयाको", - "pad.modals.reconnecting": "तमरो प्याडमि आजि: जडान हुन्नाछ", + "pad.modals.connected": "जोडीयाको।", + "pad.modals.reconnecting": "तमरा प्याडमि दोबरा जडान अद्दाछ़..", "pad.modals.forcereconnect": "बलात् पुन:जडान", + "pad.modals.reconnecttimer": "दोबरा जोड्डाइ प्रयास अद्दाछ़", + "pad.modals.cancel": "रद्द", "pad.modals.userdup": "अर्खा विण्डोमी खुलिरैछ", "pad.modals.userdup.explanation": "यो प्याड येइ कम्प्युटरमी एक़ है बर्ता ब्राउजर सञ्झ्यालमी खोल्याऽ धेकीँछ।", "pad.modals.userdup.advice": "बरु यो विण्डो प्रयोग अद्दाइ दोसर्याँ जोणिय।", @@ -63,8 +65,8 @@ "pad.modals.unauth.explanation": "येइ पन्ना हेरनज्याँ तमरा अधिकार बदेलिया। दोसर्याँ जोणिन्या प्रयास अरऽ।", "pad.modals.looping.explanation": "सिक्रोनाइजेसन सर्भर सित सञ्चार समस्या धेकिन्नाछ़।", "pad.modals.looping.cause": "शायद तम यक असंगत फायरवाल या प्रोक्सी का माध्यम बठेइ जोणीरैछऽ।", - "pad.modals.initsocketfail": "सर्भरमा पहुँच पुर्याउन नाइसकियो ।", - "pad.modals.initsocketfail.explanation": "सिङ्क्रोनाइजेसन सर्भर सित जोणीन नाइ सकियो?", + "pad.modals.initsocketfail": "सर्भरमी पहुँच पुर्याउन नाइसकियो।", + "pad.modals.initsocketfail.explanation": "सिङ्क्रोनाइजेसन सर्भर सित जोणीन नाइ सकियो।", "pad.modals.initsocketfail.cause": "यो शायद तमरा ब्राउजर या इन्टरनेट जडान सित सम्बन्धित समस्याऽ कारणले होइ सकन्छ़।", "pad.modals.slowcommit.explanation": "सर्भर प्रत्युत्तर दिन्नारेन।", "pad.modals.slowcommit.cause": "यो नेटवर्क कनेक्टिविटी सङ्ङ सम्बन्धित समस्याऽ कारण ले होइसकन्छ।", @@ -72,13 +74,13 @@ "pad.modals.badChangeset.cause": "यो यक गलत सर्भर विन्यास या केइ और अप्रत्याशित चालचलनाऽ कारण़ ले होइसकन्छ। यदि तमलाई यो गल्ती हो भण्ण्या लागन्छ भँण्या, कृपया सेवा व्यवस्थापकलाई सम्पर्क अरऽ। सम्पादन चालु राख्दाइ दोसर्याँ जोणिन्या प्रयास अरऽ।", "pad.modals.corruptPad.explanation": "तमले उपयोग अद्द़ खोज्याऽ प्याड बिगण्योऽ छ।", "pad.modals.corruptPad.cause": "यो गलत सर्भर विन्यास या केइ और नसोच्याऽ चालचलनले होइसकन्छ। कृपया सेवा व्यवस्थापकलाई सम्पर्क अरऽ।", - "pad.modals.deleted": "मेटियाको", - "pad.modals.deleted.explanation": "यो प्याड हटाइसक्याको छ ।", - "pad.modals.disconnected": "तमरो जडान अवरुद्ध भयो ।", + "pad.modals.deleted": "मेटियाको।", + "pad.modals.deleted.explanation": "यो प्याड हटाइसकीरैछ।", + "pad.modals.disconnected": "तमरो जडान अवरुद्ध भयो।", "pad.modals.disconnected.explanation": "तमरो सर्भरसितको जडान अवरुद्ध भयो", "pad.modals.disconnected.cause": "सर्भर अनुपलब्ध होइसकन्छ। यदि यो हुनोइ रयाबर कृपया सेवा व्यवस्थापकलाई सूचित अरऽ।", - "pad.share": "यस प्यडलाई बाड्न्या", - "pad.share.readonly": "पड्या मात्तरै", + "pad.share": "यस प्याडलाई बाड्न्या", + "pad.share.readonly": "पड्ड्या मात्तरै", "pad.share.link": "लिङ्क", "pad.share.emebdcode": "URL थप्प्या", "pad.chat": "कुरणिकानी", @@ -117,13 +119,13 @@ "pad.userlist.deny": "अस्वीकार", "pad.userlist.approve": "अनुमोदन", "pad.editbar.clearcolors": "सङताइ कागताजमी है लेखक रङ्ङअन साप अद्द्या?", - "pad.impexp.importbutton": "ऐलै आयार अरऽ", + "pad.impexp.importbutton": "ऐलै आयात अरऽ", "pad.impexp.importing": "आयात अद्दाछ़...", "pad.impexp.confirmimport": "फाइल आयात़ ले प्याडओ अइलओ पाठ बदेलिन्या हो। तम ऐतिऱ बड्ड चाहन्छ भणिबर पक्का छऽ?", "pad.impexp.convertFailed": "एइ फाइललाई आयात अद्द नाइसक्यो। कृपया जुदोइ कागजात फर्याट प्रयोग अरऽ या नकल पेस्ट अरऽ", "pad.impexp.padHasData": "हम एइ फाइलाई आयात अद्दाइ असमर्थ छौँ क्याइकि एइ प्याडमी पैली अरीयाऽ फेलबदेल छन्, कृपया नयाँ प्याडमी आयात अरऽ", - "pad.impexp.uploadFailed": "अपलोड असफल, कृपया दोसर्याँ प्रयास अर:", + "pad.impexp.uploadFailed": "अपलोड असफल, कृपया दोसर्याँ प्रयास अरऽ", "pad.impexp.importfailed": "आयात असफल", - "pad.impexp.copypaste": "कृपया नकल सार अर:", + "pad.impexp.copypaste": "कृपया नकल सार अरऽ", "pad.impexp.exportdisabled": "{{type}} फर्म्याटमी निर्यात अक्षम अरीरैछ। विवरण खिलाइ कृपया तमरा संयन्त्र प्रशासकलाई सम्पर्क अर:।" } diff --git a/src/locales/el.json b/src/locales/el.json index 602b82bd..2fff2e47 100644 --- a/src/locales/el.json +++ b/src/locales/el.json @@ -60,6 +60,8 @@ "pad.modals.connected": "Συνδεμένοι.", "pad.modals.reconnecting": "Επανασύνδεση στο pad σας...", "pad.modals.forcereconnect": "Επιβολή επανασύνδεσης", + "pad.modals.reconnecttimer": "Επαναπροσπάθεια σε", + "pad.modals.cancel": "Ακύρωση", "pad.modals.userdup": "Ανοιγμένο σε άλλο παράθυρο", "pad.modals.userdup.explanation": "Αυτό το pad φαίνεται να είναι ανοιχτό σε περισσότερα από ένα παράθυρο του προγράμματος περιήγησης σε αυτόν τον υπολογιστή.", "pad.modals.userdup.advice": "Επανασυνδεθείτε για να χρησιμοποιήσετε αυτό το παράθυρο.", diff --git a/src/locales/en-gb.json b/src/locales/en-gb.json index 0cae66e2..6206f773 100644 --- a/src/locales/en-gb.json +++ b/src/locales/en-gb.json @@ -2,7 +2,9 @@ "@metadata": { "authors": [ "Chase me ladies, I'm the Cavalry", - "Shirayuki" + "Shirayuki", + "Andibing", + "HairyFotr" ] }, "index.newPad": "New Pad", @@ -53,10 +55,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "You only can import from plain text or HTML formats. For more advanced import features please <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">install abiword</a>.", + "pad.importExport.abiword.innerHTML": "You only can import from plain text or HTML formats. For more advanced import features please <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">install AbiWord</a>.", "pad.modals.connected": "Connected.", "pad.modals.reconnecting": "Reconnecting to your pad..", "pad.modals.forcereconnect": "Force reconnect", + "pad.modals.reconnecttimer": "Trying to reconnect in", + "pad.modals.cancel": "Cancel", "pad.modals.userdup": "Opened in another window", "pad.modals.userdup.explanation": "This pad seems to be opened in more than one browser window on this computer.", "pad.modals.userdup.advice": "Reconnect to use this window instead.", diff --git a/src/locales/en.json b/src/locales/en.json index 3e16c5de..e438fa1b 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -40,6 +40,7 @@ "pad.settings.fontType.normal": "Normal", "pad.settings.fontType.opendyslexic": "Open Dyslexic", "pad.settings.fontType.monospaced": "Monospace", + "pad.settings.fontType.montserrat": "Montserrat", "pad.settings.fontType.comicsans": "Comic Sans", "pad.settings.fontType.couriernew": "Courier New", "pad.settings.fontType.georgia": "Georgia", @@ -47,6 +48,7 @@ "pad.settings.fontType.lucida": "Lucida", "pad.settings.fontType.lucidasans": "Lucida Sans", "pad.settings.fontType.palatino": "Palatino", + "pad.settings.fontType.robotomono": "RobotoMono", "pad.settings.fontType.tahoma": "Tahoma", "pad.settings.fontType.timesnewroman": "Times New Roman", "pad.settings.fontType.trebuchet": "Trebuchet", @@ -69,11 +71,13 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "You only can import from plain text or HTML formats. For more advanced import features please <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">install abiword</a>.", + "pad.importExport.abiword.innerHTML": "You only can import from plain text or HTML formats. For more advanced import features please <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">install AbiWord</a>.", "pad.modals.connected": "Connected.", "pad.modals.reconnecting": "Reconnecting to your pad..", "pad.modals.forcereconnect": "Force reconnect", + "pad.modals.reconnecttimer": "Trying to reconnect in ", + "pad.modals.cancel": "Cancel", "pad.modals.userdup": "Opened in another window", "pad.modals.userdup.explanation": "This pad seems to be opened in more than one browser window on this computer.", diff --git a/src/locales/eo.json b/src/locales/eo.json index 786d3bbe..2754eaf7 100644 --- a/src/locales/eo.json +++ b/src/locales/eo.json @@ -55,10 +55,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Formato “OpenDocument”)", - "pad.importExport.abiword.innerHTML": "Nur kapablas enporti de plata teksto aŭ HTML. Por pli speciala importkapablo, bonvolu <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">instalu la programon, Abiword</a>.", + "pad.importExport.abiword.innerHTML": "Nur kapablas enporti de plata teksto aŭ HTML. Por pli speciala importkapablo, bonvolu <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instalu la programon, Abiword</a>.", "pad.modals.connected": "Konektita.", "pad.modals.reconnecting": "Rekonektanta al via redaktilo..", "pad.modals.forcereconnect": "Perforte rekonekti", + "pad.modals.reconnecttimer": "Provos rekonekti post", + "pad.modals.cancel": "Nuligi", "pad.modals.userdup": "Malfermita en alia fenestro", "pad.modals.userdup.explanation": "Ĉi tiu teksto ŝajne estas malferma en pli ol unu retumilo sur ĉi tiu komputilo.", "pad.modals.userdup.advice": "Rekonekti por anstataŭe uzi ĉi tiun fenestron.", diff --git a/src/locales/es.json b/src/locales/es.json index b2659063..cc673e09 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -11,7 +11,9 @@ "Vivaelcelta", "Xuacu", "Macofe", - "Fitoschido" + "Fitoschido", + "Dgstranz", + "Luzcaru" ] }, "index.newPad": "Nuevo pad", @@ -62,10 +64,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "Solo es posible importar texto sin formato o en HTML. Para obtener funciones de importación más avanzadas es necesario <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">instalar AbiWord</a>.", + "pad.importExport.abiword.innerHTML": "Solo es posible importar texto sin formato o en HTML. Para obtener funciones de importación más avanzadas es necesario <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instalar AbiWord</a>.", "pad.modals.connected": "Conectado.", "pad.modals.reconnecting": "Reconectando a tu pad..", "pad.modals.forcereconnect": "Forzar reconexión", + "pad.modals.reconnecttimer": "Se intentará reconectar en", + "pad.modals.cancel": "Cancelar", "pad.modals.userdup": "Abierto en otra ventana", "pad.modals.userdup.explanation": "Este pad parece estar abierto en más de una ventana de tu navegador.", "pad.modals.userdup.advice": "Reconectar para usar esta ventana.", @@ -74,7 +78,7 @@ "pad.modals.looping.explanation": "Hay problemas con el servidor de sincronización.", "pad.modals.looping.cause": "Puede deberse a que te conectes a través de un proxy o un cortafuegos incompatible.", "pad.modals.initsocketfail": "Servidor incalcanzable.", - "pad.modals.initsocketfail.explanation": "No se pudo conectar al servidor de sincronización.", + "pad.modals.initsocketfail.explanation": "No se pudo conectar con el servidor de sincronización.", "pad.modals.initsocketfail.cause": "Probablemente debido a un problema en tu navegador o en tu conexión a Internet.", "pad.modals.slowcommit.explanation": "El servidor no responde.", "pad.modals.slowcommit.cause": "Puede deberse a problemas con tu conexión de red.", @@ -88,7 +92,7 @@ "pad.modals.disconnected.explanation": "Se perdió la conexión con el servidor", "pad.modals.disconnected.cause": "El servidor podría no estar disponible. Contacta al administrador del servicio si esto continúa sucediendo.", "pad.share": "Compatir este pad", - "pad.share.readonly": "Sólo lectura", + "pad.share.readonly": "Solo lectura", "pad.share.link": "Enlace", "pad.share.emebdcode": "Incrustar URL", "pad.chat": "Chat", diff --git a/src/locales/eu.json b/src/locales/eu.json index 4ef45185..fd6c3950 100644 --- a/src/locales/eu.json +++ b/src/locales/eu.json @@ -4,7 +4,9 @@ "Theklan", "Subi", "Xabier Armendaritz", - "An13sa" + "An13sa", + "Mikel Ibaiba", + "HairyFotr" ] }, "index.newPad": "Pad berria", @@ -55,10 +57,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "Testu laua edo html formatudun testuak bakarrik inporta ditzakezu. Aurreratuagoak diren inportazio aukerak izateko <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">abiword instala ezazu</a>.", + "pad.importExport.abiword.innerHTML": "Testu laua edo HTML formatudun testuak bakarrik inporta ditzakezu. Aurreratuagoak diren inportazio aukerak izateko <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">AbiWord instala ezazu</a>.", "pad.modals.connected": "Konektatuta.", "pad.modals.reconnecting": "Zure pad-era birkonektatu...", "pad.modals.forcereconnect": "Berkonexioa fortzatu", + "pad.modals.reconnecttimer": "Berriz konektatzen saiatzen", + "pad.modals.cancel": "Deuseztatu", "pad.modals.userdup": "Beste leiho batean ireki da", "pad.modals.userdup.explanation": "Pad hau zure nabigatzailearen beste leiho batean irekita dagoela ematen du.", "pad.modals.userdup.advice": "Berriro konektatu beste leiho hau erabiltzeko.", @@ -72,6 +76,9 @@ "pad.modals.slowcommit.explanation": "Zerbitzariak ez du erantzuten.", "pad.modals.slowcommit.cause": "Baliteke hau sarearen konexio arazoak direla eta izatea.", "pad.modals.badChangeset.explanation": "Sinkronizazio zerbitzariak, zuk egindako aldaketa bat legez kanpokotzat jo du.", + "pad.modals.badChangeset.cause": "Honek zerbitzariaren konfigurazio okerra edo ustekabeko beste jokabidearen baten ondorio izan liteke. Jarri harremanetan zerbitzu-administratzailearekin, errore bat dela uste baduzu. Saiatu berriro konektatzen edizioarekin jarraitzeko.", + "pad.modals.corruptPad.explanation": "Sartzen saiatzen ari zaren Pad-a hondatuta dago.", + "pad.modals.corruptPad.cause": "Baliteke zerbitzari okerreko konfigurazioa edo beste ustekabeko portaera batzuk izatea. Jarri harremanetan zerbitzu-administratzailearekin.", "pad.modals.deleted": "Ezabatua.", "pad.modals.deleted.explanation": "Pad hau ezabatua izan da.", "pad.modals.disconnected": "Deskonektatua izan zara.", @@ -92,6 +99,9 @@ "timeslider.exportCurrent": "Gorde bertsio hau honela:", "timeslider.version": "Bertsioa {{version}}", "timeslider.saved": "{{year}}ko {{month}}ren {{day}}an gordeta", + "timeslider.playPause": "Berriro erreproduzitu / gelditu Pad edukiak", + "timeslider.backRevision": "Berrikusketa bat atzerago joan Pad honetan", + "timeslider.forwardRevision": "Berrikusketa bat aurrerago joan Pad honetan", "timeslider.dateformat": "{{year}}-{{month}}-{{day}} {{hours}}:{{minutes}}:{{seconds}}", "timeslider.month.january": "Urtarrila", "timeslider.month.february": "Otsaila", @@ -107,6 +117,7 @@ "timeslider.month.december": "Abendua", "timeslider.unnamedauthors": "{{num}} izenik gabeko {[plural(num) one: egilea, other: egileak]}", "pad.savedrevs.marked": "Berrikuspen hau markatua dago gordetako berrikuspen gisa", + "pad.savedrevs.timeslider": "Gordetako berrikusketak ikus ditzakezu denbora-graduatzailea bisitatuz", "pad.userlist.entername": "Sartu zure erabiltzaile izena", "pad.userlist.unnamed": "izenik gabe", "pad.userlist.guest": "Gonbidatua", @@ -117,6 +128,7 @@ "pad.impexp.importing": "Inportatzen...", "pad.impexp.confirmimport": "Fitxategi bat inportatzen baduzu oraingo pad honen testua ezabatuko da. Ziur zaude jarraitu nahi duzula?", "pad.impexp.convertFailed": "Ez gara gai fitxategi hau inportatzeko. Erabil ezazu, mesedez, beste dokumentu formatu bat edo kopiatu eta itsasi eskuz.", + "pad.impexp.padHasData": "Artxibo hau ezin izan dugu inportatu Pad hau aldaketak izan dituelako jada, Pad berria inportatu mesedez.", "pad.impexp.uploadFailed": "Igotzean akatsa egon da, saia zaitez berriro", "pad.impexp.importfailed": "Inportazioak akatsa egin du", "pad.impexp.copypaste": "Mesedez kopiatu eta pegatu", diff --git a/src/locales/fa.json b/src/locales/fa.json index e1e88418..4b29669e 100644 --- a/src/locales/fa.json +++ b/src/locales/fa.json @@ -58,10 +58,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (قالب سند باز)", - "pad.importExport.abiword.innerHTML": "شما تنها میتوانید از قالب متن ساده یا اچتیامال درونریزی کنید. برای بیشتر شدن ویژگیهای درونریزی پیشرفته <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">AbiWord</a> را نصب کنید.", + "pad.importExport.abiword.innerHTML": "شما تنها میتوانید از قالب متن ساده یا اچتیامال درونریزی کنید. برای بیشتر شدن ویژگیهای درونریزی پیشرفته <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">AbiWord</a> را نصب کنید.", "pad.modals.connected": "متصل شد.", "pad.modals.reconnecting": "در حال اتصال دوباره به دفترچه یادداشت شما..", "pad.modals.forcereconnect": "واداشتن به اتصال دوباره", + "pad.modals.reconnecttimer": "تلاش برای اتصال مجدد", + "pad.modals.cancel": "لغو", "pad.modals.userdup": "در پنجرهای دیگر باز شد", "pad.modals.userdup.explanation": "گمان میرود این دفترچه یادداشت در بیش از یک پنجرهی مرورگر باز شدهاست.", "pad.modals.userdup.advice": "برای استفاده از این پنجره دوباره وصل شوید.", diff --git a/src/locales/fr.json b/src/locales/fr.json index 47f490c1..5f6b664a 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -22,7 +22,8 @@ "Framafan", "Fylip22", "C13m3n7", - "Wladek92" + "Wladek92", + "Urhixidur" ] }, "index.newPad": "Nouveau pad", @@ -47,13 +48,13 @@ "pad.colorpicker.save": "Enregistrer", "pad.colorpicker.cancel": "Annuler", "pad.loading": "Chargement…", - "pad.noCookie": "Le cookie n’a pas pu être trouvé. Veuillez autoriser les cookies dans votre navigateur !", + "pad.noCookie": "Le témoin (cookie) n’a pas pu être trouvé. Veuillez autoriser les témoins dans votre navigateur !", "pad.passwordRequired": "Vous avez besoin d'un mot de passe pour accéder à ce pad", "pad.permissionDenied": "Vous n'avez pas la permission d’accéder à ce pad", "pad.wrongPassword": "Votre mot de passe est incorrect", "pad.settings.padSettings": "Paramètres du pad", "pad.settings.myView": "Ma vue", - "pad.settings.stickychat": "Toujours afficher le tchat", + "pad.settings.stickychat": "Toujours afficher le clavardage", "pad.settings.chatandusers": "Afficher la discussion et les utilisateurs", "pad.settings.colorcheck": "Couleurs d’identification", "pad.settings.linenocheck": "Numéros de lignes", @@ -73,17 +74,19 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "Vous ne pouvez importer que des formats texte brut ou HTML. Pour des fonctionnalités d'importation plus évoluées, veuillez <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">installer Abiword</a>.", + "pad.importExport.abiword.innerHTML": "Vous ne pouvez importer que des formats texte brut ou HTML. Pour des fonctionnalités d'importation plus évoluées, veuillez <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">installer AbiWord</a>.", "pad.modals.connected": "Connecté.", "pad.modals.reconnecting": "Reconnexion vers votre pad...", "pad.modals.forcereconnect": "Forcer la reconnexion", + "pad.modals.reconnecttimer": "Essai de reconnexion", + "pad.modals.cancel": "Annuler", "pad.modals.userdup": "Ouvert dans une autre fenêtre", "pad.modals.userdup.explanation": "Ce pad semble être ouvert dans plusieurs fenêtres sur cet ordinateur.", "pad.modals.userdup.advice": "Se reconnecter en utilisant cette fenêtre.", "pad.modals.unauth": "Non autorisé", "pad.modals.unauth.explanation": "Vos permissions ont été changées lors de l'affichage de cette page. Essayez de vous reconnecter.", "pad.modals.looping.explanation": "Nous éprouvons un problème de communication au serveur de synchronisation.", - "pad.modals.looping.cause": "Il est possible que vous soyez connecté avec un pare-feu ou un proxy incompatible.", + "pad.modals.looping.cause": "Il est possible que vous soyez connecté avec un pare-feu ou un mandataire incompatible.", "pad.modals.initsocketfail": "Le serveur est introuvable.", "pad.modals.initsocketfail.explanation": "Impossible de se connecter au serveur de synchronisation.", "pad.modals.initsocketfail.cause": "Ceci est probablement dû à un problème avec votre navigateur ou votre connexion internet.", @@ -102,8 +105,8 @@ "pad.share.readonly": "Lecture seule", "pad.share.link": "Lien", "pad.share.emebdcode": "Incorporer un lien", - "pad.chat": "Chat", - "pad.chat.title": "Ouvrir le chat de ce pad.", + "pad.chat": "Clavardage", + "pad.chat.title": "Ouvrir le clavardoir de ce pad.", "pad.chat.loadmessages": "Charger davantage de messages", "timeslider.pageTitle": "Historique dynamique de {{appTitle}}", "timeslider.toolbar.returnbutton": "Retourner au pad", diff --git a/src/locales/gl.json b/src/locales/gl.json index ff1e9305..67491763 100644 --- a/src/locales/gl.json +++ b/src/locales/gl.json @@ -57,6 +57,8 @@ "pad.modals.connected": "Conectado.", "pad.modals.reconnecting": "Reconectando co seu documento...", "pad.modals.forcereconnect": "Forzar a reconexión", + "pad.modals.reconnecttimer": "Intentarase reconectar en", + "pad.modals.cancel": "Cancelar", "pad.modals.userdup": "Aberto noutra ventá", "pad.modals.userdup.explanation": "Semella que este documento está aberto en varias ventás do navegador neste ordenador.", "pad.modals.userdup.advice": "Reconectar para usar esta ventá.", diff --git a/src/locales/he.json b/src/locales/he.json index 3a6672b2..a857671d 100644 --- a/src/locales/he.json +++ b/src/locales/he.json @@ -55,10 +55,12 @@ "pad.importExport.exportword": "מיקרוסופט וורד", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "באפשרותך לייבא מטקסט פשוט או מ־HTML. לאפשרויות ייבוא מתקדמות יותר יש <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">להתקין את abiword</a>.", + "pad.importExport.abiword.innerHTML": "באפשרותך לייבא מטקסט פשוט או מ־HTML. לאפשרויות ייבוא מתקדמות יותר יש <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">להתקין AbiWord</a>.", "pad.modals.connected": "מחובר.", "pad.modals.reconnecting": "מתבצע חיבור מחדש...", "pad.modals.forcereconnect": "לכפות חיבור מחדש", + "pad.modals.reconnecttimer": "מנסה להתחבר מחדש בעוד", + "pad.modals.cancel": "ביטול", "pad.modals.userdup": "פתוח בחלון אחר", "pad.modals.userdup.explanation": "נראה שהפנקס הזה פתוח ביותר מחלון דפדפן אחד במחשב הזה.", "pad.modals.userdup.advice": "להתחבר מחדש באמצעות החלון הזה.", diff --git a/src/locales/hr.json b/src/locales/hr.json new file mode 100644 index 00000000..2c7190f5 --- /dev/null +++ b/src/locales/hr.json @@ -0,0 +1,129 @@ +{ + "@metadata": { + "authors": [ + "Bugoslav" + ] + }, + "index.newPad": "Novi blokić", + "index.createOpenPad": "ili stvori/otvori blokić s imenom:", + "pad.toolbar.bold.title": "Masno (Ctrl+B)", + "pad.toolbar.italic.title": "Ukošeno (Ctrl+I)", + "pad.toolbar.underline.title": "Podcrtano (Ctrl+U)", + "pad.toolbar.strikethrough.title": "Prekriženo (Ctrl+5)", + "pad.toolbar.ol.title": "Uređeni popis (Ctrl+Shift+N)", + "pad.toolbar.ul.title": "Neuređeni popis (Ctrl+Shift+L)", + "pad.toolbar.indent.title": "Uvlaka (TAB)", + "pad.toolbar.unindent.title": "Izvlaka (Shift+TAB)", + "pad.toolbar.undo.title": "Poništi (Ctrl+Z)", + "pad.toolbar.redo.title": "Ponovi (Ctrl+Y)", + "pad.toolbar.clearAuthorship.title": "Ukloni boje autorstva (Ctrl+Shift+C)", + "pad.toolbar.import_export.title": "Uvezi/izvezi iz/na različite datotečne formate", + "pad.toolbar.timeslider.title": "Pokazivač vremenske lente", + "pad.toolbar.savedRevision.title": "Spremi inačicu", + "pad.toolbar.settings.title": "Postavke", + "pad.toolbar.embed.title": "Dijeli i umetni ovaj blokić", + "pad.toolbar.showusers.title": "Pokaži suradnike ovoga blokića", + "pad.colorpicker.save": "Spremi", + "pad.colorpicker.cancel": "Otkaži", + "pad.loading": "Učitavanje...", + "pad.noCookie": "Kolačić nije pronađen. Molimo Vas da uključite kolačiće u Vašem pregledniku!", + "pad.passwordRequired": "Potrebna Vam je zaporka za pristup ovomu blokiću", + "pad.permissionDenied": "Nemate dopuštenje za pristup ovome blokiću", + "pad.wrongPassword": "Vaša zaporka nije valjana", + "pad.settings.padSettings": "Postavke blokića", + "pad.settings.myView": "Vaš prikaz", + "pad.settings.stickychat": "Stavi čavrljanje uvijek na ekranu", + "pad.settings.chatandusers": "Prikaži čavrljanje i suradnike", + "pad.settings.colorcheck": "Boje autorstva", + "pad.settings.linenocheck": "Brojevi redaka", + "pad.settings.rtlcheck": "Želite li prikaz sadržaja s desna na lijevo?", + "pad.settings.fontType": "Vrsta fonta:", + "pad.settings.globalView": "Globalni prikaz", + "pad.settings.language": "Jezik:", + "pad.importExport.import_export": "Uvoz/Izvoz", + "pad.importExport.import": "Postavite bilo koju tekstualnu datoteku ili dokument", + "pad.importExport.importSuccessful": "Uspješno!", + "pad.importExport.export": "Izvezi trenutačni blokić kao:", + "pad.importExport.exportetherpad": "Etherpad (virtualni blokići)", + "pad.importExport.exporthtml": "HTML (oblikovanje sadržaja)", + "pad.importExport.exportplain": "Obični tekst (bez oblikovanja)", + "pad.importExport.exportword": "Datoteku programa Microsoft Word", + "pad.importExport.exportpdf": "Datoteku Acrobatova PDF formata", + "pad.importExport.exportopen": "Datoteku formata Open Document (ODF)", + "pad.importExport.abiword.innerHTML": "Možete uvoziti datoteke formata za obični tekst (bez oblikovanja) te datoteke u HTML-u. Za naprednije mogućnosti uvoza molimo Vas, instalirajte <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">program AbiWord</a>.", + "pad.modals.connected": "Povezano.", + "pad.modals.reconnecting": "Ponovo Vas povezujemo s Vašim blokićem...", + "pad.modals.forcereconnect": "Prisilno se ponovo poveži", + "pad.modals.reconnecttimer": "Sustav Vas pokušava ponovo povezati", + "pad.modals.cancel": "Odustani", + "pad.modals.userdup": "Otvoreno u drugom prozoru", + "pad.modals.userdup.explanation": "Čini se da je ovaj blokić otvoren u više od jednoga prozora Vašega preglednika na ovom računalu.", + "pad.modals.userdup.advice": "Ponovo se povežite da biste rabili ovaj prozor.", + "pad.modals.unauth": "Niste ovlašteni", + "pad.modals.unauth.explanation": "Vaše su ovlasti promijenjene za vrijeme dok ste pregledavali stranicu.\nPokušajte se ponovo spojiti.", + "pad.modals.looping.explanation": "Postoje komunikacijski problemi sa sinkronizacijskim poslužiteljem.", + "pad.modals.looping.cause": "Možda ste se spojili preko nekompatibilne sigurnosne stijene ili proxyja.", + "pad.modals.initsocketfail": "Poslužitelj nije dostupan.", + "pad.modals.initsocketfail.explanation": "Ne mogu se povezati sa sinkronizacijskim poslužiteljem.", + "pad.modals.initsocketfail.cause": "Najvjerojatnije je došlo do problema s Vašim preglednikom ili s Vašom internetskom vezom.", + "pad.modals.slowcommit.explanation": "Poslužitelj ne šalje odziv.", + "pad.modals.slowcommit.cause": "Najvjerojatnije je došlo do problema s dostupnošću mreže.", + "pad.modals.badChangeset.explanation": "Sinkronizacijski poslužitelj označio je Vaše uređivanje kao nedopušteno.", + "pad.modals.badChangeset.cause": "Moguće je da je došlo do pogrješke konfiguracije poslužitelja ili nekog drugog neočekivanog događaja odnosno postupka. Molimo Vas da kontaktirate s Vašim administratorom usluge, ukoliko držite da je ovo pogrješka. Molimo Vas, pokušajte se ponovo spojiti kako biste nastavili s uređivanjem.", + "pad.modals.corruptPad.explanation": "Blokić kom pokušavate pristupiti je oštećen.", + "pad.modals.corruptPad.cause": "Moguće je došlo do pogrješne konfiguracije poslužitelja ili nekog drugog neočekivanog događaja ili postupka. Molimo Vas, kontaktirajte administratora usluge.", + "pad.modals.deleted": "Pobrisano.", + "pad.modals.deleted.explanation": "Blokić je bio uklonjen.", + "pad.modals.disconnected": "Vaša je veza prekinuta.", + "pad.modals.disconnected.explanation": "Veza s poslužiteljem je izgubljena.", + "pad.modals.disconnected.cause": "Moguće je da poslužitelj nije dostupan. Molimo Vas, obavijestite administratora usluge ukoliko se to nastavi događati.", + "pad.share": "Dijeljenje ovoga blokića.", + "pad.share.readonly": "Samo za čitanje", + "pad.share.link": "Poveznica", + "pad.share.emebdcode": "Umetni poveznicu (URL)", + "pad.chat": "Čavrljanje", + "pad.chat.title": "Otvori čavrljanje uz ovaj blokić.", + "pad.chat.loadmessages": "Učitaj više poruka", + "timeslider.pageTitle": "{{appTitle}} Vremenska lenta", + "timeslider.toolbar.returnbutton": "Vrati se natrag na blokić", + "timeslider.toolbar.authors": "Autori:", + "timeslider.toolbar.authorsList": "Nema autora", + "timeslider.toolbar.exportlink.title": "Izvoz", + "timeslider.exportCurrent": "Izvezi trenutačnu inačicu kao:", + "timeslider.version": "Inačica {{version}}", + "timeslider.saved": "Spremljeno dana {{day}}. {{month}} {{year}}.", + "timeslider.playPause": "Izvrti/pauziraj sadržaj blokića", + "timeslider.backRevision": "Idi jednu inačicu ovog blokića natrag", + "timeslider.forwardRevision": "Idi jednu inačicu ovog blokića naprijed", + "timeslider.dateformat": "{{day}}. {{month}}. {{year}}. {{hours}}:{{minutes}}:{{seconds}}", + "timeslider.month.january": "siječnja", + "timeslider.month.february": "veljače", + "timeslider.month.march": "ožujka", + "timeslider.month.april": "travnja", + "timeslider.month.may": "svibnja", + "timeslider.month.june": "lipnja", + "timeslider.month.july": "srpnja", + "timeslider.month.august": "kolovoza", + "timeslider.month.september": "rujna", + "timeslider.month.october": "listopada", + "timeslider.month.november": "studenoga", + "timeslider.month.december": "prosinca", + "timeslider.unnamedauthors": "{{num}} {[plural(num) one: neimenovani autor, plural(num) two: neimenovana autora, plural(num) other: neimenovanih autora ]}", + "pad.savedrevs.marked": "Ova inačica označena je sada kao spremljena inačica", + "pad.savedrevs.timeslider": "Možete vidjeti spremljene inačice rabeći vremensku lentu (timeslider)", + "pad.userlist.entername": "Unesite Vaše suradničko ime", + "pad.userlist.unnamed": "bez imena", + "pad.userlist.guest": "Gost", + "pad.userlist.deny": "Odbij", + "pad.userlist.approve": "Odobri", + "pad.editbar.clearcolors": "Ukloniti boje autorstva u cijelom blokiću?", + "pad.impexp.importbutton": "Uvezi odmah", + "pad.impexp.importing": "Uvoženje...", + "pad.impexp.confirmimport": "Uvoženje datoteke presnimit će trenutačni sadržaj blokića.\nJeste li sigurni da želite nastaviti?", + "pad.impexp.convertFailed": "Nismo bili u mogućnosti uvesti tu datoteku. Molimo Vas, rabite neki drugi format dokumenta ili ručno preslikajte/zalijepite sadržaj", + "pad.impexp.padHasData": "Nismo bili u mogućnosti uvesti navedenu datoteku, jer je blokić već bio mijenjan, molimo Vas uvezite u novi blokić", + "pad.impexp.uploadFailed": "Postavljanje nije uspjelo. molimo Vas, pokušajte ponovo", + "pad.impexp.importfailed": "Uvoz nije uspio", + "pad.impexp.copypaste": "Molimo preslikajte/zalijepite", + "pad.impexp.exportdisabled": "Izvoz u formatu {{type}} nije omogućen. Molimo Vas, kontaktirajte Vašega administratora sustava za više pojedinosti." +} diff --git a/src/locales/hu.json b/src/locales/hu.json index f34c76ca..e8045a7c 100644 --- a/src/locales/hu.json +++ b/src/locales/hu.json @@ -5,14 +5,16 @@ "Misibacsi", "R-Joe", "Tgr", - "Csega" + "Csega", + "BanKris", + "Notramo" ] }, "index.newPad": "Új notesz", "index.createOpenPad": "vagy notesz létrehozása/megnyitása ezzel a névvel:", - "pad.toolbar.bold.title": "Félkövér (Ctrl-B)", - "pad.toolbar.italic.title": "Dőlt (Ctrl-I)", - "pad.toolbar.underline.title": "Aláhúzás (Ctrl-U)", + "pad.toolbar.bold.title": "Félkövér (Ctrl+B)", + "pad.toolbar.italic.title": "Dőlt (Ctrl+I)", + "pad.toolbar.underline.title": "Aláhúzás (Ctrl+U)", "pad.toolbar.strikethrough.title": "Áthúzás (Ctrl+5)", "pad.toolbar.ol.title": "Számozott lista (Ctrl+Shift+N)", "pad.toolbar.ul.title": "Számozatlan lista (Ctrl+Shift+L)", @@ -60,6 +62,8 @@ "pad.modals.connected": "Kapcsolódva.", "pad.modals.reconnecting": "Újrakapcsolódás a noteszhez...", "pad.modals.forcereconnect": "Újrakapcsolódás kényszerítése", + "pad.modals.reconnecttimer": "Megpróbálok újracsatlakozni ennyi múlva:", + "pad.modals.cancel": "Mégse", "pad.modals.userdup": "Új ablakban megnyitva", "pad.modals.userdup.explanation": "Úgy tűnik, ez a notesz több különböző böngészőablakban is meg van nyitva a számítógépeden.", "pad.modals.userdup.advice": "Kapcsolódj újra, ha ezt az ablakot akarod használni.", @@ -112,7 +116,7 @@ "timeslider.month.october": "október", "timeslider.month.november": "november", "timeslider.month.december": "december", - "timeslider.unnamedauthors": "{{num}} névtelen {[plural(num), one: szerző, other: szerzők]}", + "timeslider.unnamedauthors": "{{num}} névtelen {[plural(num), one: szerző, other: szerző]}", "pad.savedrevs.marked": "Ez a revízió mostantól mentettként jelölve", "pad.savedrevs.timeslider": "A mentett revíziókat az időcsúszkán tudod megnézni", "pad.userlist.entername": "Add meg a nevedet", diff --git a/src/locales/hy.json b/src/locales/hy.json index 672905c5..20e0026c 100644 --- a/src/locales/hy.json +++ b/src/locales/hy.json @@ -29,6 +29,7 @@ "pad.importExport.exportpdf": "PDF", "pad.modals.connected": "Կապված է", "pad.modals.forcereconnect": "Հարկադիր վերամիավորել", + "pad.modals.cancel": "Չեղարկել", "pad.modals.userdup": "Բաց է մյուս պատուհանում", "pad.modals.initsocketfail": "Սերվերը անհասանելի է ։", "pad.modals.slowcommit.explanation": "Սերվերը չի պատասխանում։", diff --git a/src/locales/ia.json b/src/locales/ia.json index 64d3bf6e..9a3fd31e 100644 --- a/src/locales/ia.json +++ b/src/locales/ia.json @@ -56,6 +56,8 @@ "pad.modals.connected": "Connectite.", "pad.modals.reconnecting": "Reconnecte a tu pad…", "pad.modals.forcereconnect": "Fortiar reconnexion", + "pad.modals.reconnecttimer": "Tentativa de reconnexion in", + "pad.modals.cancel": "Cancellar", "pad.modals.userdup": "Aperte in un altere fenestra", "pad.modals.userdup.explanation": "Iste pad pare esser aperte in plus de un fenestra de navigator in iste computator.", "pad.modals.userdup.advice": "Reconnecte pro usar iste fenestra.", diff --git a/src/locales/is.json b/src/locales/is.json index 61065cb7..3d51bd72 100644 --- a/src/locales/is.json +++ b/src/locales/is.json @@ -57,6 +57,8 @@ "pad.modals.connected": "Tengt.", "pad.modals.reconnecting": "Endurtengist skrifblokkinni þinni...", "pad.modals.forcereconnect": "Þvinga endurtengingu", + "pad.modals.reconnecttimer": "Reyni aftur að tengjast eftir", + "pad.modals.cancel": "Hætta við", "pad.modals.userdup": "Opnað í öðrum glugga", "pad.modals.userdup.explanation": "Þessi skrifblokk virðist vera opin í fleiri en einum vafraglugga á þessari tölvu.", "pad.modals.userdup.advice": "Endurtengdu til að nota þennan glugga í staðinn.", diff --git a/src/locales/it.json b/src/locales/it.json index aab7513b..d7d7c095 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -57,10 +57,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "È possibile importare solo i formati di testo semplice o HTML. Per metodi più avanzati di importazione <a href=https://github.com/broadcast/etherpad-lite/wiki/How-to-enable-importing and exporting-different file formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord>installare Abiword</a>.", + "pad.importExport.abiword.innerHTML": "È possibile importare solo i formati di testo semplice o HTML. Per metodi più avanzati di importazione <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">installare AbiWord</a>.", "pad.modals.connected": "Connesso.", "pad.modals.reconnecting": "Riconnessione al pad in corso...", "pad.modals.forcereconnect": "Forza la riconnessione", + "pad.modals.reconnecttimer": "Tentativo di riconnessione", + "pad.modals.cancel": "Annulla", "pad.modals.userdup": "Aperto in un'altra finestra", "pad.modals.userdup.explanation": "Questo Pad sembra essere aperto in più di una finestra del browser su questo computer.", "pad.modals.userdup.advice": "Riconnettiti per utilizzare invece questa finestra.", diff --git a/src/locales/ja.json b/src/locales/ja.json index f223a8c4..aeb6ba7d 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -2,7 +2,8 @@ "@metadata": { "authors": [ "Shirayuki", - "Torinky" + "Torinky", + "Omotecho" ] }, "index.newPad": "新規作成", @@ -57,6 +58,8 @@ "pad.modals.connected": "接続されました。", "pad.modals.reconnecting": "パッドに再接続中...", "pad.modals.forcereconnect": "強制的に再接続", + "pad.modals.reconnecttimer": "再接続を試行中", + "pad.modals.cancel": "中止", "pad.modals.userdup": "別のウィンドウで開かれています", "pad.modals.userdup.explanation": "このコンピューターの複数のブラウザーウィンドウで、このパッドを開いているようです。", "pad.modals.userdup.advice": "代わりにこのウィンドウを再接続します。", diff --git a/src/locales/kab.json b/src/locales/kab.json new file mode 100644 index 00000000..905c3855 --- /dev/null +++ b/src/locales/kab.json @@ -0,0 +1,129 @@ +{ + "@metadata": { + "authors": [ + "Belkacem77" + ] + }, + "index.newPad": "Apad amaynut", + "index.createOpenPad": "neɣ rnu/ldi apad s yisem:", + "pad.toolbar.bold.title": "Zur (Ctrl+B)", + "pad.toolbar.italic.title": "Uknan (Ctrl+I)", + "pad.toolbar.underline.title": "Ituderrer (Ctrl+U)", + "pad.toolbar.strikethrough.title": "Ittujerreḍ (Ctrl+5)", + "pad.toolbar.ol.title": "Tabdart n usmizzwer (Ctrl+Shift+N)", + "pad.toolbar.ul.title": "Tabdart s war asmizzwer (Ctrl+Shift+L)", + "pad.toolbar.indent.title": "Rigel (TAB)", + "pad.toolbar.unindent.title": "Kkes ariger (Shift+TAB)", + "pad.toolbar.undo.title": "Sefsex (Ctrl+Z)", + "pad.toolbar.redo.title": "Err-d (Ctrl+Y)", + "pad.toolbar.clearAuthorship.title": "Sfeḍ initen yemmalen imeskaren (Ctrl+Shift+C)", + "pad.toolbar.import_export.title": "Kter/Sifeḍ seg/ɣer umasal n ufaylu-nnḍen", + "pad.toolbar.timeslider.title": "Amazray asmussan", + "pad.toolbar.savedRevision.title": "Sekles aceggir", + "pad.toolbar.settings.title": "Iɣewwaṛen", + "pad.toolbar.embed.title": "Bḍu sakin seddu apad-agi", + "pad.toolbar.showusers.title": "Sken iseqdacen ɣef upad-agi", + "pad.colorpicker.save": "Sekles", + "pad.colorpicker.cancel": "Sefsex", + "pad.loading": "Asali...", + "pad.noCookie": "Anagi n tuqqna ulac-it. Sireg inagan n tuqqna deg iminig-ik!", + "pad.passwordRequired": "Tesriḍ awal uffir akken ad tkecmeḍ ar upad-agi", + "pad.permissionDenied": "Ur ɣur-k ara tasiregt akken ad tkecmeḍ ar upad-agi", + "pad.wrongPassword": "Awal-uhhir mačči d ameɣtu", + "pad.settings.padSettings": "Iɣewwaṛen n upad", + "pad.settings.myView": "Timeẓri-iw", + "pad.settings.stickychat": "Asqerdec yezga deg ugdil", + "pad.settings.chatandusers": "Sken asqerdec akken iseqdacen", + "pad.settings.colorcheck": "Initen n usulu", + "pad.settings.linenocheck": "Uṭṭunen n izirigen", + "pad.settings.rtlcheck": "Ɣeṛ agbur seg uyeffus s azelmaḍ?", + "pad.settings.fontType": "Anaw n tsefsit:", + "pad.settings.globalView": "Timeẓri tamatut:", + "pad.settings.language": "Tutlayt:", + "pad.importExport.import_export": "Kter/Sifeḍ", + "pad.importExport.import": "Sali aḍris neɣ isemli", + "pad.importExport.importSuccessful": "Yedda!", + "pad.importExport.export": "Sifeḍ apad amiran am:", + "pad.importExport.exportetherpad": "Etherpad", + "pad.importExport.exporthtml": "HTML", + "pad.importExport.exportplain": "Adris aččuran", + "pad.importExport.exportword": "Microsoft Word", + "pad.importExport.exportpdf": "PDF", + "pad.importExport.exportopen": "ODF (Open Document Format)", + "pad.importExport.abiword.innerHTML": "Tzemreḍ kan ad ketreḍ aḍris aččuran neɣ imasalen HTML. Ugar n tmahilin n ukter leqqayen, rzu ar <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">Sebded AbiWord</a>.", + "pad.modals.connected": "Iqqen.", + "pad.modals.reconnecting": "Tulsa n tuqqna ar upad-ik.", + "pad.modals.forcereconnect": "Ḥettem tulsa n tuqqna", + "pad.modals.reconnecttimer": "Ɛreḍ tikelt-nniḍen tuqqna", + "pad.modals.cancel": "Sefsex", + "pad.modals.userdup": "Yeldi deg usfaylu-nniḍen", + "pad.modals.userdup.explanation": "Apad-agi yettban yeldi deg isfuyla-nniḍen deg uselkim-agi.", + "pad.modals.userdup.advice": "Ales tuqqna akken ad tesqedceḍ asfaylu-agi.", + "pad.modals.unauth": "Ur uettwasireg ara", + "pad.modals.unauth.explanation": "Tisirag-ik beddlent makken ad d-yettwaskan usebter. Ɛreḍ ad teqqneḍ.", + "pad.modals.looping.explanation": "Nufa-d uguren n teywalt akked uqeddac n umtawi.", + "pad.modals.looping.cause": "Ahat teqqneḍ s uɣrab n tmes neɣ apṛuksi ur yemṣadan ara", + "pad.modals.initsocketfail": "Ulac aqeddac.", + "pad.modals.initsocketfail.explanation": "Ur izmir ara ad yeqqen ar uqeddac n umtawi.", + "pad.modals.initsocketfail.cause": "Ahat d ugur i d-yekkan seg iminig-ik neɣ tuqqna ar Internet.", + "pad.modals.slowcommit.explanation": "Aqeddac ur d-yettara ara awal.", + "pad.modals.slowcommit.cause": "Ahat d ugur i d-yekkan seg tuqqna ar uẓeṭṭa.", + "pad.modals.badChangeset.explanation": "Abeddel i tgiḍ yettwammel d ayen ur ilaqen ara deg uqeddac n umtawi.", + "pad.modals.badChangeset.cause": "Ahat ayagi yekka-d si yir tawila n uqeddac neɣ kra n wayen ur nerǧi ara. Nermes anebdal n umeẓlu, ma yella tḥulfaḍ d tuccḍa. Ɛreḍ tuqqna akken ad tkemmleḍ taẓrigt.", + "pad.modals.corruptPad.explanation": "Apad i tettaɣraḍeḍ ad tkecmeḍ yexseṛ.", + "pad.modals.corruptPad.cause": "Ayagi ahat yekka-d seg yir tawila n uqeddac neɣ ayen ur yettwaṛǧan ara. Nermes anebdal n umeẓlu.", + "pad.modals.deleted": "Yettwakkes.", + "pad.modals.deleted.explanation": "Apad-agi yettwakkes.", + "pad.modals.disconnected": "Suffren-k.", + "pad.modals.disconnected.explanation": "Tuqqna ar uqeddac truḥ", + "pad.modals.disconnected.cause": "Ahat aqeddac ulac-it. Nermes anebdal n umeẓlu ma yella yezga iḍeṛṛu", + "pad.share": "Bḍu apad-agi", + "pad.share.readonly": "Taɣuri kan", + "pad.share.link": "Aseɣwen", + "pad.share.emebdcode": "Seddu URL", + "pad.chat": "Asqerdec", + "pad.chat.title": "Ldi asqerdec deg upad-agi.", + "pad.chat.loadmessages": "Sali-d ugar n yiznan", + "timeslider.pageTitle": "Amazray asmussan n {{appTitle}}", + "timeslider.toolbar.returnbutton": "Uqal ar upad", + "timeslider.toolbar.authors": "Imeskaren:", + "timeslider.toolbar.authorsList": "Ulac imeskaren", + "timeslider.toolbar.exportlink.title": "Sifeḍ", + "timeslider.exportCurrent": "Sifeḍ lqem-agi amiran am:", + "timeslider.version": "Lqem {{version}}", + "timeslider.saved": "Yettwasekles deg {{day}}-{{month}}-{{year}}", + "timeslider.playPause": "Taɣuri/Aserǧu n igburen n upad", + "timeslider.backRevision": "Uɣal s yiwen n uceggir ar deffir deg upad-agi", + "timeslider.forwardRevision": "Ddu ar zdat s yiwen n uceggir deg upad-agi", + "timeslider.dateformat": "{{day}}-{{month}}-{{year}} {{hours}}:{{minutes}}:{{seconds}}", + "timeslider.month.january": "Yennayer", + "timeslider.month.february": "Fuṛaṛ", + "timeslider.month.march": "Meɣres", + "timeslider.month.april": "Yebrir", + "timeslider.month.may": "Mayyu", + "timeslider.month.june": "Yunyu", + "timeslider.month.july": "Yulyu", + "timeslider.month.august": "Ɣuct", + "timeslider.month.september": "Ctamber", + "timeslider.month.october": "Tuber", + "timeslider.month.november": "Wamber", + "timeslider.month.december": "Dujamber", + "timeslider.unnamedauthors": "{{num}}{[plural(num) one: ameskar udrig, other: imeskaren udrigen]}", + "pad.savedrevs.marked": "Aceggir-agi yettwacreḍ tura d aceggir yettwaskelsen", + "pad.savedrevs.timeslider": "Tzemreḍ ad waliḍ iceggiren yettwaskelsen ticki teldiḍ amazray", + "pad.userlist.entername": "Sekcem isem-ik", + "pad.userlist.unnamed": "udrig", + "pad.userlist.guest": "Inebgi", + "pad.userlist.deny": "Agwi", + "pad.userlist.approve": "Qbel", + "pad.editbar.clearcolors": "Sfeḍ akk initen icudden ar imeskaren deg isemliyen meṛṛa?", + "pad.impexp.importbutton": "Kter tura", + "pad.impexp.importing": "Aktar iteddu...", + "pad.impexp.confirmimport": "Akter n ufaylu ad yesfeɛj aḍris amiran deg upad. Tebɣiḍ ad tkemleḍ?", + "pad.impexp.convertFailed": "Ur nezmir ara ad d-nekter afaylu-agi. Ma ulac aɣilif seqdec amasal n isemli-nniḍen neɣ nɣel/senteḍ s ufus.", + "pad.impexp.padHasData": "Ur nezmir ara ad d-nekter afaylu-agi acku apad-agi ibeddel yakan, ma ulac aɣilif, kter ar upad amaynut", + "pad.impexp.uploadFailed": "Asali yecceḍ, ma ulac aɣilif ɛreḍ tikelt-nniḍen", + "pad.impexp.importfailed": "Akter ur yeddi ara", + "pad.impexp.copypaste": "Ma ulac aɣilif nɣel/senteḍ", + "pad.impexp.exportdisabled": "Aɣewwaṛ n usifeḍ s umasal{{type}} yensa. Nermes anebdal-ik n unagraw i ugar n telqayt." +} diff --git a/src/locales/ko.json b/src/locales/ko.json index d0ba7bdc..19625eae 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -6,7 +6,8 @@ "Revi", "Kurousagi", "SeoJeongHo", - "Ykhwong" + "Ykhwong", + "CYAN" ] }, "index.newPad": "새 패드", @@ -27,7 +28,7 @@ "pad.toolbar.savedRevision.title": "판 저장", "pad.toolbar.settings.title": "설정", "pad.toolbar.embed.title": "이 패드를 공유하고 포함하기", - "pad.toolbar.showusers.title": "이 패드에 사용자 보기", + "pad.toolbar.showusers.title": "이 패드의 사용자 보기", "pad.colorpicker.save": "저장", "pad.colorpicker.cancel": "취소", "pad.loading": "불러오는 중...", @@ -38,7 +39,7 @@ "pad.settings.padSettings": "패드 설정", "pad.settings.myView": "내 보기", "pad.settings.stickychat": "화면에 항상 대화 보기", - "pad.settings.chatandusers": "채트와 사용자 보기", + "pad.settings.chatandusers": "대화와 사용자 보기", "pad.settings.colorcheck": "저자 색", "pad.settings.linenocheck": "줄 번호", "pad.settings.rtlcheck": "우횡서(오른쪽에서 왼쪽으로)입니까?", @@ -54,19 +55,21 @@ "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "일반 텍스트", - "pad.importExport.exportword": "Microsoft Word", + "pad.importExport.exportword": "마이크로소프트 워드", "pad.importExport.exportpdf": "PDF", - "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "일반 텍스트나 html 형식으로만 가져올 수 있습니다. 고급 가져오기 기능에 대해서는 <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">abiword를 설치</a>하세요.", + "pad.importExport.exportopen": "ODF (Open Document Format, 개방형 문서 형식)", + "pad.importExport.abiword.innerHTML": "일반 텍스트나 HTML 형식으로만 가져올 수 있습니다. 고급 가져오기 기능에 대해서는 <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">AbiWord를 설치</a>하세요.", "pad.modals.connected": "연결했습니다.", "pad.modals.reconnecting": "패드에 다시 연결 중..", "pad.modals.forcereconnect": "강제로 다시 연결", - "pad.modals.userdup": "다른 창에서 열리고 있습니다", - "pad.modals.userdup.explanation": "이 패드는 이 컴퓨터에 하나보다 많이 브라우저 창에서 열린 것 같습니다.", + "pad.modals.reconnecttimer": "다시 접속 시도 중", + "pad.modals.cancel": "취소", + "pad.modals.userdup": "다른 창에서 열렸습니다", + "pad.modals.userdup.explanation": "이 패드는 이 컴퓨터에 하나 이상의 브라우저 창에서 열린 것 같습니다.", "pad.modals.userdup.advice": "대신 이 창을 사용해 다시 연결합니다.", "pad.modals.unauth": "권한이 없음", - "pad.modals.unauth.explanation": "이 문서를 보는 동안 권한이 바뀌었습니다. 다시 연결을 시도하세요.", - "pad.modals.looping.explanation": "동기 서버와의 통신 문제가 있습니다.", + "pad.modals.unauth.explanation": "이 페이지를 보는 동안 권한이 바뀌었습니다. 연결을 다시 시도하세요.", + "pad.modals.looping.explanation": "동기화 서버와 통신 문제가 있습니다.", "pad.modals.looping.cause": "아마 호환되지 않는 방화벽이나 프록시를 통해 연결되어 있습니다.", "pad.modals.initsocketfail": "서버에 연결할 수 없습니다.", "pad.modals.initsocketfail.explanation": "동기 서버에 연결할 수 없습니다.", diff --git a/src/locales/lb.json b/src/locales/lb.json index 50cebaf2..2f1432a6 100644 --- a/src/locales/lb.json +++ b/src/locales/lb.json @@ -45,6 +45,7 @@ "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", "pad.modals.connected": "Verbonnen.", + "pad.modals.cancel": "Ofbriechen", "pad.modals.userdup": "An enger anerer Fënster opgemaach", "pad.modals.unauth": "Net autoriséiert", "pad.modals.unauth.explanation": "Är Rechter hu geännert während deem Dir dës säit gekuckt hutt. Probéiert fir Iech nei ze connectéieren.", diff --git a/src/locales/lv.json b/src/locales/lv.json index b860055a..7c0bc96c 100644 --- a/src/locales/lv.json +++ b/src/locales/lv.json @@ -48,6 +48,7 @@ "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open dokumenta formāts)", "pad.modals.connected": "Pievienojies.", + "pad.modals.cancel": "Atcelt", "pad.modals.userdup": "Atvērts citā logā", "pad.modals.unauth": "Nav atļauts", "pad.modals.looping.explanation": "Pastāv sakaru problēmas ar sinhronizācijas servera.", diff --git a/src/locales/mg.json b/src/locales/mg.json new file mode 100644 index 00000000..5279bdf3 --- /dev/null +++ b/src/locales/mg.json @@ -0,0 +1,90 @@ +{ + "@metadata": { + "authors": [ + "Jagwar" + ] + }, + "index.newPad": "Pad vaovao", + "index.createOpenPad": "na hamorona/hanokatra Pad manana anarana:", + "pad.toolbar.bold.title": "Matevina (Ctrl-B)", + "pad.toolbar.italic.title": "Mandry (Ctrl-L)", + "pad.toolbar.underline.title": "Tsipihana (Ctrl-U)", + "pad.toolbar.strikethrough.title": "Voatsipika", + "pad.toolbar.ol.title": "Lisitra nalamina", + "pad.toolbar.ul.title": "Lisitra tsy voalamina", + "pad.toolbar.undo.title": "Averina (Ctrl-Z)", + "pad.toolbar.redo.title": "Averina (Ctrl-Y)", + "pad.toolbar.clearAuthorship.title": "Hanala ny loko famantarana mpanorona", + "pad.toolbar.import_export.title": "Hampiditra/Hamoaka amin'ny karazan-drakitra hafa", + "pad.toolbar.settings.title": "Fanafahana", + "pad.colorpicker.save": "Tehirizina", + "pad.colorpicker.cancel": "Aoka ihany", + "pad.loading": "Am-pakàna…", + "pad.permissionDenied": "Tsy manana lalalana mijery ity pad ity ianao", + "pad.wrongPassword": "Diso ny tenimiafinao", + "pad.settings.padSettings": "Safidin'ny ped", + "pad.settings.myView": "Ny jeriko", + "pad.settings.linenocheck": "Laharan'ny andalana", + "pad.settings.rtlcheck": "Hamaky ny votoatiny miankavia?", + "pad.settings.fontType": "Karazan-tarehintsoratra:", + "pad.settings.globalView": "Jery ankapobe", + "pad.settings.language": "Fiteny:", + "pad.importExport.import_export": "Hampiditra/Hamoaka", + "pad.importExport.import": "Hampiditra raki-tsoratra na rakitra", + "pad.importExport.importSuccessful": "Vita soa aman-tsara!", + "pad.importExport.export": "Hamoaka ny pad ankehitriny ho:", + "pad.importExport.exportetherpad": "Etherpad", + "pad.importExport.exporthtml": "HTML", + "pad.importExport.exportplain": "Soratra tsotra", + "pad.importExport.exportword": "Microsoft Word", + "pad.importExport.exportpdf": "PDF", + "pad.importExport.exportopen": "ODF (Open Document Format)", + "pad.modals.connected": "Tafaray.", + "pad.modals.forcereconnect": "Hanery ny famerenam-pifandraisana", + "pad.modals.reconnecttimer": "Manandrana mamerim-pifandraisana", + "pad.modals.cancel": "Aoka ihany", + "pad.modals.userdup": "Nosokafana tanaty varavarankely hafa", + "pad.modals.unauth": "Tsy nahazo alalana", + "pad.modals.initsocketfail": "Tsy hita ny lohamilina.", + "pad.modals.slowcommit.explanation": "Tsy mamaly ny lohamilina", + "pad.modals.slowcommit.cause": "Izany zavatra izany dia mety nohon'ny fifandraisana ratsy amin'ny lohamilina.", + "pad.modals.badChangeset.explanation": "Voasokajin'ny lohamilim-pirindrana ho tsy azo atao ny fiovana nataonao.", + "pad.modals.badChangeset.cause": "Izany zavatra izany dia mety nohon'ny configuration lohamilina diso na hetsika tsy nampoizina hafa. Mifandraisa amin'ny mpandrindran'ny serivisy, raha heverinao fa hadisoana io. Mifandraisa indray ahafahanao manohy ny fanovana.", + "pad.modals.deleted": "Voafafa.", + "pad.modals.deleted.explanation": "Nesorina ity pad ity.", + "pad.modals.disconnected": "Tapaka ny fifandraisanao.", + "pad.modals.disconnected.explanation": "Very ny fifandraisana tamin'ny lohamilina", + "pad.share": "Hizara ity pad ity", + "pad.share.readonly": "Vakiana ihany", + "pad.share.link": "Rohy", + "pad.share.emebdcode": "Hampiditra URL", + "pad.chat": "Resaka mivantana", + "pad.chat.title": "Hampiditra ny karajia ho an'ity pad ity.", + "pad.chat.loadmessages": "Haka hafatra be kokoa", + "timeslider.pageTitle": "Tantara dinamikan'i {{appTitle}}", + "timeslider.toolbar.returnbutton": "Hiverina amin'ny pad", + "timeslider.toolbar.authors": "Mpamorona:", + "timeslider.toolbar.authorsList": "Tsy misy mpamorona", + "timeslider.toolbar.exportlink.title": "Avoaka", + "timeslider.exportCurrent": "Hamoaka ny versiona ankehitriny ho:", + "timeslider.version": "Versiona {{version}}", + "timeslider.saved": "Notahirizina ny {{day}} {{month}} {{year}}", + "timeslider.month.january": "Janoary", + "timeslider.month.february": "Febroary", + "timeslider.month.march": "Martsa", + "timeslider.month.april": "Aprily", + "timeslider.month.may": "Mey", + "timeslider.month.june": "Jiona", + "timeslider.month.july": "Jolay", + "timeslider.month.august": "Aogositra", + "timeslider.month.september": "Septambra", + "timeslider.month.october": "Oktobra", + "timeslider.month.november": "Novambra", + "timeslider.month.december": "Desambra", + "pad.userlist.unnamed": "tsy manana naarana", + "pad.userlist.guest": "Nasaina", + "pad.userlist.deny": "Lavina", + "pad.userlist.approve": "Ekena", + "pad.impexp.importbutton": "Ampidirina izao", + "pad.impexp.importing": "Mampiditra..." +} diff --git a/src/locales/mk.json b/src/locales/mk.json index e292efa6..2ca04171 100644 --- a/src/locales/mk.json +++ b/src/locales/mk.json @@ -57,6 +57,8 @@ "pad.modals.connected": "Поврзано.", "pad.modals.reconnecting": "Ве преповрзувам со тетратката...", "pad.modals.forcereconnect": "Наметни преповрзување", + "pad.modals.reconnecttimer": "Се преповрзувам за", + "pad.modals.cancel": "Откажи", "pad.modals.userdup": "Отворено во друг прозорец", "pad.modals.userdup.explanation": "Оваа тетратка е отворена на повеќе од еден прозорец (во прелистувач) на сметачот.", "pad.modals.userdup.advice": "Преповрзете се за да го користите овој прозорец.", diff --git a/src/locales/ms.json b/src/locales/ms.json index 93b421fa..e23fa30a 100644 --- a/src/locales/ms.json +++ b/src/locales/ms.json @@ -1,7 +1,8 @@ { "@metadata": { "authors": [ - "Anakmalaysia" + "Anakmalaysia", + "Jeluang Terluang" ] }, "index.newPad": "Pad baru", @@ -69,7 +70,7 @@ "pad.modals.slowcommit.explanation": "Pelayan tidak membalas.", "pad.modals.slowcommit.cause": "Ini mungkin disebabkan oleh masalah dengan kesambungan rangkaian anda.", "pad.modals.badChangeset.explanation": "Suntingan yang telah anda lakukan telah dikira sebagai terlarang oleh pelayan penyegerakan.", - "pad.modals.badChangeset.cause": "Ini mungkin disebabkan oleh konfigurasi pelayan salah atau sesuatu kelakuan yang tidak dijangka. Sila hubungi penyelia servis anda jika anda merasakan ini adalah satu kesilapan. Cuba sambungkan semula talian untuk terus menyuntung.", + "pad.modals.badChangeset.cause": "Hal ini mungkin disebabkan oleh konfigurasi pelayan salah atau sesuatu kelakuan yang tidak dijangka. Sila hubungi penyelia servis anda jika anda merasakan ini ialah satu kesilapan. Cuba sambungkan semula talian untuk terus menyunting.", "pad.modals.corruptPad.explanation": "Pad yang anda cuba akses itu telah tercemar.", "pad.modals.corruptPad.cause": "Ini mungkin disebabkan oleh konfigurasi pelayan salah atau sesuatu kelakuan yang tidak dijangka. Sila hubungi penyelia servis anda.", "pad.modals.deleted": "Dihapuskan.", diff --git a/src/locales/nb.json b/src/locales/nb.json index 5c46b7de..06293aa8 100644 --- a/src/locales/nb.json +++ b/src/locales/nb.json @@ -4,7 +4,8 @@ "Laaknor", "Cocu", "Chameleon222", - "SuperPotato" + "SuperPotato", + "Jon Harald Søby" ] }, "index.newPad": "Ny Pad", @@ -59,6 +60,8 @@ "pad.modals.connected": "Tilkoblet.", "pad.modals.reconnecting": "Kobler til din blokk på nytt...", "pad.modals.forcereconnect": "Tving gjenoppkobling", + "pad.modals.reconnecttimer": "Prøver å koble til igjen", + "pad.modals.cancel": "Avbryt", "pad.modals.userdup": "Åpnet i nytt vindu", "pad.modals.userdup.explanation": "Denne blokken ser ut til å være åpnet i mer enn et nettleservindu på denne maskinen.", "pad.modals.userdup.advice": "Koble til igjen for å bruke dette vinduet i stedenfor.", diff --git a/src/locales/nl.json b/src/locales/nl.json index b01df7a3..727e8abe 100644 --- a/src/locales/nl.json +++ b/src/locales/nl.json @@ -59,6 +59,8 @@ "pad.modals.connected": "Verbonden.", "pad.modals.reconnecting": "Opnieuw verbinding maken met uw pad...", "pad.modals.forcereconnect": "Opnieuw verbinden", + "pad.modals.reconnecttimer": "Proberen te verbinden over", + "pad.modals.cancel": "Annuleren", "pad.modals.userdup": "In een ander venster geopend", "pad.modals.userdup.explanation": "Dit pad is meer dan één keer geopend in een browservenster op deze computer.", "pad.modals.userdup.advice": "Maak opnieuw verbinding als u dit venster wilt gebruiken.", diff --git a/src/locales/oc.json b/src/locales/oc.json index 00944531..5ec80904 100644 --- a/src/locales/oc.json +++ b/src/locales/oc.json @@ -52,10 +52,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "Podètz pas importar que de formats tèxte brut o html. Per de foncionalitats d'importacion mai evoluadas, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">installatz abiword</a>.", + "pad.importExport.abiword.innerHTML": "Podètz pas importar que de formats tèxte brut o html. Per de foncionalitats d'importacion mai evoluadas, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">installatz abiword</a>.", "pad.modals.connected": "Connectat.", "pad.modals.reconnecting": "Reconnexion cap a vòstre Pad...", "pad.modals.forcereconnect": "Forçar la reconnexion.", + "pad.modals.reconnecttimer": "Ensag de reconnexion", + "pad.modals.cancel": "Anullar", "pad.modals.userdup": "Dobèrt dins una autra fenèstra", "pad.modals.userdup.explanation": "Sembla qu'aqueste Pad es dobèrt dins mai d'una fenèstra de vòstre navigador sus aqueste ordinator.", "pad.modals.userdup.advice": "Se reconnectar en utilizant aquesta fenèstra.", @@ -91,7 +93,7 @@ "timeslider.toolbar.exportlink.title": "Exportar", "timeslider.exportCurrent": "Exportar la version actuala en :", "timeslider.version": "Version {{version}}", - "timeslider.saved": "Enregistrat lo {{day}} {{month}} {{year}}", + "timeslider.saved": "Enregistrat lo {{day}} de {{month}} de {{year}}", "timeslider.playPause": "Lectura / Pausa dels contenguts del pad", "timeslider.backRevision": "Recular d’una revision dins aqueste pad", "timeslider.forwardRevision": "Avançar d’una revision dins aqueste pad", diff --git a/src/locales/pl.json b/src/locales/pl.json index 85bbf474..c2632878 100644 --- a/src/locales/pl.json +++ b/src/locales/pl.json @@ -7,7 +7,8 @@ "Woytecr", "Macofe", "Pan Cube", - "Mateon1" + "Mateon1", + "Teeed" ] }, "index.newPad": "Nowy dokument", @@ -19,7 +20,7 @@ "pad.toolbar.ol.title": "Lista uporządkowana (Ctrl+Shift+N)", "pad.toolbar.ul.title": "Lista nieuporządkowana (Ctrl+Shift+L)", "pad.toolbar.indent.title": "Wcięcie (TAB)", - "pad.toolbar.unindent.title": "Wcięcie (Shift + TAB)", + "pad.toolbar.unindent.title": "Usunięcie wcięcia (Shift + TAB)", "pad.toolbar.undo.title": "Cofnij (Ctrl-Z)", "pad.toolbar.redo.title": "Ponów (Ctrl-Y)", "pad.toolbar.clearAuthorship.title": "Usuń kolory autorów (Ctrl+Shift+C)", @@ -32,7 +33,7 @@ "pad.colorpicker.save": "Zapisz", "pad.colorpicker.cancel": "Anuluj", "pad.loading": "Ładowanie...", - "pad.noCookie": "Nie znaleziono pliku cookie. Proszę zezwolić pliki cookie w przeglądarce!", + "pad.noCookie": "Nie znaleziono pliku cookie. Proszę zezwolić na pliki cookie w przeglądarce!", "pad.passwordRequired": "Musisz podać hasło aby uzyskać dostęp do tego dokumentu", "pad.permissionDenied": "Nie masz uprawnień dostępu do tego dokumentu", "pad.wrongPassword": "Nieprawidłowe hasło", @@ -62,6 +63,8 @@ "pad.modals.connected": "Połączony.", "pad.modals.reconnecting": "Ponowne łączenie z dokumentem...", "pad.modals.forcereconnect": "Wymuś ponowne połączenie", + "pad.modals.reconnecttimer": "Trwa próba ponownego połączenia", + "pad.modals.cancel": "Anuluj", "pad.modals.userdup": "Otwarty w innym oknie", "pad.modals.userdup.explanation": "Ten dokument prawdopodobnie został otwarty w więcej niż jednym oknie przeglądarki.", "pad.modals.userdup.advice": "Połącz ponownie przy użyciu tego okna.", @@ -73,9 +76,9 @@ "pad.modals.initsocketfail.explanation": "Nie udało się połączyć z serwerem synchronizacji.", "pad.modals.initsocketfail.cause": "Prawdopodobnie jest to spowodowane problemami z przeglądarką lub połączeniem internetowym.", "pad.modals.slowcommit.explanation": "Serwer nie odpowiada.", - "pad.modals.slowcommit.cause": "Może być to spowodowane problemami z Twoim połączeniem z siecią.", - "pad.modals.badChangeset.explanation": "Edycja, którą wykonałeś, została niewłaściwie zakwalifikowana przez serwer synchronizacji.", - "pad.modals.badChangeset.cause": "Może być to spowodowane złą konfiguracją serwera lub innym nieoczekiwanym zachowaniem. Skontaktuj się z administratorem serwisu, jeżeli wydaje Ci się, że to jest błąd. Spróbuj ponownie połączyć się aby kontynuować edycję.", + "pad.modals.slowcommit.cause": "Może być to spowodowane problemami z Twoim połączeniem sieciowym.", + "pad.modals.badChangeset.explanation": "Edycja, którą wykonałeś, została uznana przez serwer synchronizacji jako niepoprawna.", + "pad.modals.badChangeset.cause": "Może być to spowodowane złą konfiguracją serwera lub innym nieoczekiwanym zachowaniem. Skontaktuj się z administratorem serwisu, jeżeli wydaje Ci się, że to jest błąd. Spróbuj połączyć się ponownie aby kontynuować edycję.", "pad.modals.corruptPad.explanation": "Dokument, do którego próbujesz uzyskać dostęp, jest uszkodzony.", "pad.modals.corruptPad.cause": "Może być to spowodowane złą konfiguracją serwera lub innym nieoczekiwanym zachowaniem. Skontaktuj się z administratorem serwisu.", "pad.modals.deleted": "Usunięto.", @@ -98,7 +101,7 @@ "timeslider.exportCurrent": "Eksportuj bieżącą wersję jako:", "timeslider.version": "Wersja {{version}}", "timeslider.saved": "Zapisano {{day}} {{month}} {{year}}", - "timeslider.playPause": "Odtwarzaj / pauzuj zawartość dokumentu", + "timeslider.playPause": "Odtwarzaj / zatrzymaj przewijanie historii dokumentu", "timeslider.backRevision": "Przejdź do poprzedniej wersji dokumentu", "timeslider.forwardRevision": "Przejdź do następnej wersji dokumentu", "timeslider.dateformat": "{{year}}-{{month}}-{{day}} {{hours}}:{{minutes}}:{{seconds}}", diff --git a/src/locales/pt-br.json b/src/locales/pt-br.json index e356041f..d72a7128 100644 --- a/src/locales/pt-br.json +++ b/src/locales/pt-br.json @@ -15,7 +15,8 @@ "Fasouzafreitas", "Lpagliari", "Walesson", - "Cainamarques" + "Cainamarques", + "Eduardo Addad de Oliveira" ] }, "index.newPad": "Nova Nota", @@ -70,6 +71,8 @@ "pad.modals.connected": "Conectado.", "pad.modals.reconnecting": "Reconectando à sua nota...", "pad.modals.forcereconnect": "Forçar reconexão", + "pad.modals.reconnecttimer": "Tentando se reconectar", + "pad.modals.cancel": "Cancelar", "pad.modals.userdup": "Aberto em outra janela", "pad.modals.userdup.explanation": "Esta nota parece estar aberta em mais de uma janela de navegador deste computador.", "pad.modals.userdup.advice": "Reconectar para usar esta janela.", diff --git a/src/locales/qqq.json b/src/locales/qqq.json index 0beec0cc..60d62b19 100644 --- a/src/locales/qqq.json +++ b/src/locales/qqq.json @@ -58,6 +58,7 @@ "pad.modals.connected": "Used as HTML <code><nowiki><h2></nowiki></code> heading to indicate the status.\n\nSee also:\n* {{msg-etherpadlite|Pad.modals.reconnecting}}\n{{Identical|Connected}}", "pad.modals.reconnecting": "Used as HTML <code><nowiki><h2></nowiki></code> heading to indicate the status.\n\nSee also:\n* {{msg-etherpadlite|Pad.modals.connected}}", "pad.modals.forcereconnect": "Label of a button that will make the browser reconnect to the synchronization server.", + "pad.modals.cancel": "{{Identical|Cancel}}", "pad.modals.userdup": "Used as HTML <code><nowiki><h1></nowiki></code> heading to indicate that the pad is opened in another window on this computer.\n\nFollowed by the following messages:\n* {{msg-etherpadlite|Pad.modals.userdup.explanation}} - <code><nowiki><h2></nowiki></code> heading\n* {{msg-etherpadlite|Pad.modals.userdup.advice}}", "pad.modals.userdup.explanation": "Used as HTML <code><nowiki><h2></nowiki></code> heading.\n\nPreceded by the parent heading {{msg-etherpadlite|Pad.modals.userdup}}.\n\nFollowed by the message {{msg-etherpadlite|Pad.modals.userdup.advice}}.", "pad.modals.userdup.advice": "Preceded by the following headings:\n* {{msg-etherpadlite|Pad.modals.userdup}}\n* {{msg-etherpadlite|Pad.modals.userdup.explanation}}", diff --git a/src/locales/ru.json b/src/locales/ru.json index 2d92b1b6..b9fbc3c8 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -6,7 +6,8 @@ "Eleferen", "Okras", "Volkov", - "Nzeemin" + "Nzeemin", + "Facenapalm" ] }, "index.newPad": "Создать", @@ -61,6 +62,8 @@ "pad.modals.connected": "Подключен.", "pad.modals.reconnecting": "Повторное подключение к вашему документу", "pad.modals.forcereconnect": "Принудительное переподключение", + "pad.modals.reconnecttimer": "Попытка переподключения", + "pad.modals.cancel": "Отмена", "pad.modals.userdup": "Открыто в другом окне", "pad.modals.userdup.explanation": "Документ, возможно, открыт более чем в одном окне браузера на этом компьютере.", "pad.modals.userdup.advice": "Повторно подключить с использованием этого окна.", diff --git a/src/locales/sco.json b/src/locales/sco.json index f7b01824..274a85b4 100644 --- a/src/locales/sco.json +++ b/src/locales/sco.json @@ -1,7 +1,8 @@ { "@metadata": { "authors": [ - "John Reid" + "John Reid", + "AmaryllisGardener" ] }, "index.newPad": "New Pad", @@ -9,14 +10,14 @@ "pad.toolbar.bold.title": "Bold (Ctrl-B)", "pad.toolbar.italic.title": "Italic (Ctrl-I)", "pad.toolbar.underline.title": "Underline (Ctrl-U)", - "pad.toolbar.strikethrough.title": "Cross-oot", - "pad.toolbar.ol.title": "Ordered leet", - "pad.toolbar.ul.title": "Onordered Leet", + "pad.toolbar.strikethrough.title": "Strikethrou (Ctrl+5)", + "pad.toolbar.ol.title": "Ordered leet (Ctrl+Shift+N)", + "pad.toolbar.ul.title": "Unordered Leet (Ctrl+Shift+L)", "pad.toolbar.indent.title": "Indent (TAB)", "pad.toolbar.unindent.title": "Ootdent (Shift+TAB)", "pad.toolbar.undo.title": "Ondae (Ctrl-Z)", "pad.toolbar.redo.title": "Redae (Ctrl-Y)", - "pad.toolbar.clearAuthorship.title": "Clear Authorship Colours", + "pad.toolbar.clearAuthorship.title": "Clear Authorship Colours (Ctrl+Shift+C)", "pad.toolbar.import_export.title": "Import/Export fae/til different file formats", "pad.toolbar.timeslider.title": "Timeslider", "pad.toolbar.savedRevision.title": "Hain Reveesion", @@ -26,12 +27,14 @@ "pad.colorpicker.save": "Hain", "pad.colorpicker.cancel": "Cancel", "pad.loading": "Laidin...", + "pad.noCookie": "Cookie could nae be foond. Please allae cookies in yer brouser!", "pad.passwordRequired": "Ye need ae passwaird fer tae access this pad", "pad.permissionDenied": "Ye dinna hae permeession tae access this pad", "pad.wrongPassword": "Yer password wis wrang", "pad.settings.padSettings": "Pad Settins", "pad.settings.myView": "Ma Luik", "pad.settings.stickychat": "Tauk aye oan screen", + "pad.settings.chatandusers": "Shaw Chat an Uisers", "pad.settings.colorcheck": "Authorship colours", "pad.settings.linenocheck": "Line nummers", "pad.settings.rtlcheck": "Read content fae richt til cair?", @@ -44,6 +47,7 @@ "pad.importExport.import": "Upload oni tex file or document", "pad.importExport.importSuccessful": "Success!", "pad.importExport.export": "Export current pad as:", + "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "Plain tex", "pad.importExport.exportword": "Microsoft Word", @@ -89,6 +93,9 @@ "timeslider.exportCurrent": "Export current version as:", "timeslider.version": "Version {{version}}", "timeslider.saved": "Saved {{day}} {{month}}, {{year}}", + "timeslider.playPause": "Playback / Pause Pad Contents", + "timeslider.backRevision": "Gae back a reveesion in this Pad", + "timeslider.forwardRevision": "Gae forwart a reveesion in this Pad", "timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}", "timeslider.month.january": "Januair", "timeslider.month.february": "Febuair", @@ -104,6 +111,7 @@ "timeslider.month.december": "Dizember", "timeslider.unnamedauthors": "{{num}} onnamed {[plural(num) one: writer, other: writers ]}", "pad.savedrevs.marked": "This reveesion is nou tagged aes ae hained reveesion", + "pad.savedrevs.timeslider": "Ye can see saved reveesions bi veesitin the timeslider", "pad.userlist.entername": "Enter yer name", "pad.userlist.unnamed": "onnamed", "pad.userlist.guest": "Guest", @@ -114,6 +122,7 @@ "pad.impexp.importing": "Importing...", "pad.impexp.confirmimport": "Importin ae file will owerwrite the current tex o the pad. Ar ye sair ye want tae proceed?", "pad.impexp.convertFailed": "We coudna import this file. Please uise ae different document format or copy paste manually", + "pad.impexp.padHasData": "We war nae able tae import this file acause this Pad haes awready haed chynges, please import tae a new pad", "pad.impexp.uploadFailed": "The upload failed, please try again", "pad.impexp.importfailed": "The import failed", "pad.impexp.copypaste": "Please copy paste", diff --git a/src/locales/sk.json b/src/locales/sk.json index 445adc00..e199945a 100644 --- a/src/locales/sk.json +++ b/src/locales/sk.json @@ -4,7 +4,8 @@ "Teslaton", "Kusavica", "Rudko", - "Mark" + "Mark", + "Lexected" ] }, "index.newPad": "Nový Pad", @@ -29,12 +30,14 @@ "pad.colorpicker.save": "Uložiť", "pad.colorpicker.cancel": "Zrušiť", "pad.loading": "Načítava sa...", + "pad.noCookie": "Cookie nebolo možné nájsť. Povoľte prosím cookies vo vašom prehliadači.", "pad.passwordRequired": "Prístup k tomuto Padu je chránený heslom", "pad.permissionDenied": "Ľutujeme, nemáte oprávnenie pristupovať k tomuto Padu", "pad.wrongPassword": "Nesprávne heslo", "pad.settings.padSettings": "Nastavenia Padu", "pad.settings.myView": "Vlastný pohľad", "pad.settings.stickychat": "Chat stále na obrazovke", + "pad.settings.chatandusers": "Zobraziť chat a užívateľov", "pad.settings.colorcheck": "Farby autorstva", "pad.settings.linenocheck": "Čísla riadkov", "pad.settings.rtlcheck": "Čítať obsah sprava doľava?", @@ -53,10 +56,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "Importovať môžete len čistý text alebo HTML. Pre pokročilejšie funkcie importu prosím nainštalujte „<a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">Abiword</a>“.", + "pad.importExport.abiword.innerHTML": "Importovať môžete len čistý text alebo HTML. Pre pokročilejšie funkcie importu prosím nainštalujte „<a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">AbiWord</a>“.", "pad.modals.connected": "Pripojené.", "pad.modals.reconnecting": "Opätovné pripájanie k vášmu Padu...", "pad.modals.forcereconnect": "Vynútiť znovupripojenie", + "pad.modals.reconnecttimer": "Skúšam sa pripojiť", + "pad.modals.cancel": "Zrušiť", "pad.modals.userdup": "Otvorené v inom okne", "pad.modals.userdup.explanation": "Zdá sa, že tento Pad je na tomto počítači otvorený vo viacerých oknách prehliadača.", "pad.modals.userdup.advice": "Pre použitie tohoto okna se musíte znovu pripojiť.", @@ -93,6 +98,9 @@ "timeslider.exportCurrent": "Exportovať aktuálnu verziu ako:", "timeslider.version": "Verzia {{version}}", "timeslider.saved": "Uložené {{day}}. {{month}} {{year}}", + "timeslider.playPause": "Pustiť / Pozastaviť obsah padu", + "timeslider.backRevision": "Ísť v tomto pade a revíziu späť", + "timeslider.forwardRevision": "Ísť v tomto pade o revíziu vpred", "timeslider.dateformat": "{{day}}. {{month}} {{year}} {{hours}}:{{minutes}}:{{seconds}}", "timeslider.month.january": "januára", "timeslider.month.february": "februára", @@ -108,6 +116,7 @@ "timeslider.month.december": "decembra", "timeslider.unnamedauthors": "{{num}} {[ plural(num) one: nemenovaný autor, few: nemenovaní autori, other: nemenovaných autorov ]}", "pad.savedrevs.marked": "Táto revízia bola označená ako uložená", + "pad.savedrevs.timeslider": "Návštevou časovej osi môžete zobraziť uložené revízie", "pad.userlist.entername": "Zadajte svoje meno", "pad.userlist.unnamed": "nemenovaný", "pad.userlist.guest": "Hosť", @@ -118,6 +127,7 @@ "pad.impexp.importing": "Prebieha import...", "pad.impexp.confirmimport": "Import súboru prepíše celý súčasný obsah Padu. Skutočne si želáte vykonať túto akciu?", "pad.impexp.convertFailed": "Tento súbor nie je možné importovať. Použite prosím iný formát súboru alebo nakopírujte text manuálne", + "pad.impexp.padHasData": "Nebolo možné importovať tento súbor, pretože tento pad už bol pozmenený. Importujte prosím súbor do nového padu", "pad.impexp.uploadFailed": "Nahrávanie zlyhalo, skúste to prosím znovu", "pad.impexp.importfailed": "Import zlyhal", "pad.impexp.copypaste": "Vložte prosím kópiu cez schránku", diff --git a/src/locales/skr-arab.json b/src/locales/skr-arab.json new file mode 100644 index 00000000..833d341e --- /dev/null +++ b/src/locales/skr-arab.json @@ -0,0 +1,69 @@ +{ + "@metadata": { + "authors": [ + "Saraiki" + ] + }, + "index.newPad": "نواں پیڈ", + "pad.toolbar.bold.title": "بولڈ(Ctrl+B)", + "pad.toolbar.italic.title": "ترچھے (Ctrl+I)", + "pad.toolbar.underline.title": "ہیٹھ لکیر (Ctrl+U)", + "pad.toolbar.savedRevision.title": "رویژن بچاؤ", + "pad.toolbar.settings.title": "ترتیباں", + "pad.colorpicker.save": "بچاؤ", + "pad.colorpicker.cancel": "منسوخ", + "pad.loading": "لوڈ تھیندا پئے۔۔۔", + "pad.wrongPassword": "تہاݙ پاسورڈ غلط ہے", + "pad.settings.padSettings": "پیڈ ترتیباں", + "pad.settings.fontType": "فونٹ قسم:", + "pad.settings.globalView": "عالمی منظر", + "pad.settings.language": "زبان:", + "pad.importExport.importSuccessful": "کامیاب!", + "pad.importExport.exportetherpad": "ایتھرپیڈ", + "pad.importExport.exporthtml": "ایچ ٹی ایم ایل", + "pad.importExport.exportplain": "سادہ متن", + "pad.importExport.exportword": "مائیکروسافٹ ورڈ", + "pad.importExport.exportpdf": "پی ڈی ایف", + "pad.modals.connected": "ڄُڑ ڳیا۔", + "pad.modals.cancel": "منسوخ", + "pad.modals.unauth": "اجازت کائنی", + "pad.modals.initsocketfail": "سرور تائیں پہنچݨ ممکن کائنی", + "pad.modals.slowcommit.explanation": "سرور توں جواب کائنی امدا پیا", + "pad.modals.deleted": "مٹا ݙتے", + "pad.modals.deleted.explanation": "ایہ پیڈ ہٹا ݙتا ڳئے۔", + "pad.modals.disconnected": "تہاݙا کنکشن مُک ڳئے", + "pad.share": "ایہ پیڈ شیئر کرو", + "pad.share.readonly": "صرف پڑھو", + "pad.share.link": "ربط", + "pad.share.emebdcode": "امنیڈ یو آر ایل", + "pad.chat": "چیٹ", + "pad.chat.loadmessages": "ٻئے سنیہے لوڈ کرو", + "timeslider.toolbar.returnbutton": "واپس پیڈ تے ونڄو", + "timeslider.toolbar.authors": "مصنف:", + "timeslider.toolbar.authorsList": "کوئی مصنف کائنی", + "timeslider.toolbar.exportlink.title": "ٻاہر بھیڄو", + "timeslider.version": "ورژن {{version}}", + "timeslider.saved": "محفوظ تھیا {{month}} {{day}}, {{year}}", + "timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}", + "timeslider.month.january": "جنوری", + "timeslider.month.february": "فروری", + "timeslider.month.march": "مارچ", + "timeslider.month.april": "اپريل", + "timeslider.month.may": "مئی", + "timeslider.month.june": "جون", + "timeslider.month.july": "جولائی", + "timeslider.month.august": "اگست", + "timeslider.month.september": "ستمبر", + "timeslider.month.october": "اکتوبر", + "timeslider.month.november": "نومبر", + "timeslider.month.december": "دسمبر", + "pad.userlist.entername": "آپݨا ناں درج کرو", + "pad.userlist.unnamed": "بغیر ناں", + "pad.userlist.guest": "پرہاݨاں", + "pad.userlist.deny": "انکار", + "pad.userlist.approve": "منظور", + "pad.impexp.importbutton": "ہݨ ٻاہروں گھن آؤ", + "pad.impexp.importing": "اندر آندا پئے۔۔۔", + "pad.impexp.uploadFailed": "فائل اپ لوڈ نی تھی سڳی، چڑھاوݨ کیتےولدا کوشش کرو", + "pad.impexp.importfailed": "ٻاہروں آ نی سڳے" +} diff --git a/src/locales/sl.json b/src/locales/sl.json index 5d2dd85e..50333132 100644 --- a/src/locales/sl.json +++ b/src/locales/sl.json @@ -3,7 +3,8 @@ "authors": [ "Dbc334", "Mateju", - "Skalcaa" + "Skalcaa", + "HairyFotr" ] }, "index.newPad": "Nov dokument", @@ -18,23 +19,23 @@ "pad.toolbar.unindent.title": "Zamik levo (Shift+TAB)", "pad.toolbar.undo.title": "Razveljavi (Ctrl-Z)", "pad.toolbar.redo.title": "Ponovno uveljavi (Ctrl-Y)", - "pad.toolbar.clearAuthorship.title": "Počisti barvo avtorstva (Ctrl+Shift+C)", + "pad.toolbar.clearAuthorship.title": "Počisti barve avtorstva (Ctrl+Shift+C)", "pad.toolbar.import_export.title": "Izvozi/Uvozi različne oblike zapisov", - "pad.toolbar.timeslider.title": "Drsnik zgodovine", - "pad.toolbar.savedRevision.title": "Shrani predelavo", + "pad.toolbar.timeslider.title": "Časovni trak", + "pad.toolbar.savedRevision.title": "Shrani redakcijo", "pad.toolbar.settings.title": "Nastavitve", - "pad.toolbar.embed.title": "Deli in vključi dokument", + "pad.toolbar.embed.title": "Deli in vključi ta dokument", "pad.toolbar.showusers.title": "Pokaži uporabnike dokumenta", "pad.colorpicker.save": "Shrani", "pad.colorpicker.cancel": "Prekliči", "pad.loading": "Nalaganje ...", "pad.noCookie": "Piškotka ni bilo mogoče najti. Prosimo, dovolite piškotke v vašem brskalniku!", - "pad.passwordRequired": "Za dostop do dokumenta je zahtevano geslo.", - "pad.permissionDenied": "Za dostop do dokumenta so zahtevana posebna dovoljenja.", - "pad.wrongPassword": "Vpisano geslo je napačno.", + "pad.passwordRequired": "Za dostop do dokumenta potrebujete geslo.", + "pad.permissionDenied": "Nimate dovoljenja za dostop do tega dokumenta.", + "pad.wrongPassword": "Vpisano geslo je napačno", "pad.settings.padSettings": "Nastavitve dokumenta", - "pad.settings.myView": "Pogled", - "pad.settings.stickychat": "Vsebina klepeta je vedno na zaslonu.", + "pad.settings.myView": "Moj pogled", + "pad.settings.stickychat": "Vsebina klepeta je vedno na zaslonu", "pad.settings.chatandusers": "Prikaži klepet in uporabnike", "pad.settings.colorcheck": "Barve avtorstva", "pad.settings.linenocheck": "Številke vrstic", @@ -54,41 +55,43 @@ "pad.importExport.exportword": "DOC (zapis Microsoft Word)", "pad.importExport.exportpdf": "PDF (zapis Acrobat PDF)", "pad.importExport.exportopen": "ODF (zapis Open Document)", - "pad.importExport.abiword.innerHTML": "Uvoziti je mogoče le običajno neoblikovano besedilo in zapise HTML. Za naprednejše zmožnosti namestite <a href=\\\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\\\">program Abiword</a>.", + "pad.importExport.abiword.innerHTML": "Uvoziti je mogoče le običajno neoblikovano besedilo in zapise HTML. Za naprednejše zmožnosti namestite <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">program AbiWord</a>.", "pad.modals.connected": "Povezano.", "pad.modals.reconnecting": "Poteka povezovanje z dokumentom ...", - "pad.modals.forcereconnect": "Vsili ponovno povezavo.", - "pad.modals.userdup": "Dokument je že odprt v v drugem oknu.", + "pad.modals.forcereconnect": "Vsili ponovno povezavo", + "pad.modals.reconnecttimer": "Poskus ponovne vzpostavitve povezave čez", + "pad.modals.cancel": "Prekliči", + "pad.modals.userdup": "Dokument je že odprt v v drugem oknu", "pad.modals.userdup.explanation": "Videti je, da je ta dokument odprt v več kot enem oknu brskalnika na tem računalniku.", "pad.modals.userdup.advice": "Ponovno vzpostavite povezavo in uporabljajte to okno.", "pad.modals.unauth": "Nepooblaščen dostop", - "pad.modals.unauth.explanation": "Med pregledovanjem te strani so se dovoljenja za ogled spremenila. Treba se bo znova povezati.", - "pad.modals.looping.explanation": "Zaznane so težave s povezavo za usklajevanje s strežnikom.", - "pad.modals.looping.cause": "Morda je vzpostavljena povezava preko neustrezno nastavljenega požarnega zidu ali posredniškega strežnika.", - "pad.modals.initsocketfail": "Dostop do strežnika ni mogoč.", + "pad.modals.unauth.explanation": "Med pregledovanjem te strani so se dovoljenja za ogled spremenila. Poskusite se ponovno povezati.", + "pad.modals.looping.explanation": "Zaznane so težave pri komunikaciji s strežnikom za usklajevanje.", + "pad.modals.looping.cause": "Morda ste se povezali preko neustrezno nastavljenega požarnega zidu ali posredniškega strežnika.", + "pad.modals.initsocketfail": "Strežnika je nedosegljiv.", "pad.modals.initsocketfail.explanation": "Povezava s strežnikom za usklajevanje ni mogoča.", - "pad.modals.initsocketfail.cause": "Najverjetneje je težava v brskalniku, ali pa so težave z internetno povezavo.", + "pad.modals.initsocketfail.cause": "Najverjetneje gre za težavo z vašim brskalnikom, ali internetno povezavo.", "pad.modals.slowcommit.explanation": "Strežnik se ne odziva.", - "pad.modals.slowcommit.cause": "Najverjetneje je prišlo do napake med vzpostavitvijo povezave.", - "pad.modals.badChangeset.explanation": "Urejanje, ki ste ga naredili, je sinhronizacijski strežnik označil kot nelegalno.", - "pad.modals.badChangeset.cause": "Razlog za to je morda napačna konfiguracija strežnika ali neko drugo nepričakovano vedenje. Prosimo, stopite v stik z upravljavcem storitve, če menite, da gre za napako. Poskusite se ponovno povezati, da nadaljujete z urejanjem.", + "pad.modals.slowcommit.cause": "Možen vzrok so težave z omrežno povezljivostjo.", + "pad.modals.badChangeset.explanation": "Urejanje, ki ste ga naredili, je strežnik za usklajevanje označil kot nedovoljeno.", + "pad.modals.badChangeset.cause": "Razlog za to je morda napačna konfiguracija strežnika ali neko drugo nepričakovano vedenje. Prosimo, stopite v stik z skrbnikom storitve, če menite, da gre za napako. Poskusite se ponovno povezati, da nadaljujete z urejanjem.", "pad.modals.corruptPad.explanation": "Dokument, do katerega želite dostopati, je poškodovan.", - "pad.modals.corruptPad.cause": "Razlog za to je morda napačna konfiguracija strežnika ali neko drugo nepričakovano vedenje. Prosimo, stopite v stik z upravljavcem storitve.", + "pad.modals.corruptPad.cause": "Razlog za to je morda napačna konfiguracija strežnika ali neko drugo nepričakovano vedenje. Prosimo, stopite v stik s skrbnikom storitve.", "pad.modals.deleted": "Izbrisano.", - "pad.modals.deleted.explanation": "Dokument je odstranjen.", - "pad.modals.disconnected": "Povezava je prekinjena.", - "pad.modals.disconnected.explanation": "Povezava s strežnikom je bila prekinjena.", - "pad.modals.disconnected.cause": "Strežnik je morda nedosegljiv. Prosimo, obvestite skrbnika storitve, če se to zgodi večkrat.", + "pad.modals.deleted.explanation": "Dokument je bil odstranjen.", + "pad.modals.disconnected": "Vaša povezava je bila prekinjena.", + "pad.modals.disconnected.explanation": "Povezava s strežnikom je bila izgubljena.", + "pad.modals.disconnected.cause": "Strežnik morda ni na voljo. Prosimo, obvestite skrbnika storitve, če se to zgodi večkrat.", "pad.share": "Določi souporabo dokumenta", "pad.share.readonly": "Le za branje", "pad.share.link": "Povezava", - "pad.share.emebdcode": "Vstavi naslov URL", + "pad.share.emebdcode": "URL za vključitev", "pad.chat": "Klepet", "pad.chat.title": "Odpri klepetalno okno dokumenta.", "pad.chat.loadmessages": "Naloži več sporočil", - "timeslider.pageTitle": "Zgodovina dokumenta {{appTitle}}", + "timeslider.pageTitle": "Časovni trak {{appTitle}}", "timeslider.toolbar.returnbutton": "Vrni se na dokument", - "timeslider.toolbar.authors": "Autorji:", + "timeslider.toolbar.authors": "Avtorji:", "timeslider.toolbar.authorsList": "Ni določenih avtorjev", "timeslider.toolbar.exportlink.title": "Izvozi", "timeslider.exportCurrent": "Izvozi trenutno različico kot:", @@ -96,7 +99,7 @@ "timeslider.saved": "Shranjeno {{day}}.{{month}}.{{year}}", "timeslider.playPause": "Predvajaj/začasno ustavi vsebino dokumenta", "timeslider.backRevision": "Pojdi eno redakcijo nazaj v tem dokumentu", - "timeslider.forwardRevision": "Pojdi redakcijo naprej v tem dokumentu", + "timeslider.forwardRevision": "Pojdi eno redakcijo naprej v tem dokumentu", "timeslider.dateformat": "{{day}}.{{month}}.{{year}} {{hours}}:{{minutes}}:{{seconds}}", "timeslider.month.january": "Januar", "timeslider.month.february": "Februar", @@ -111,9 +114,9 @@ "timeslider.month.november": "November", "timeslider.month.december": "December", "timeslider.unnamedauthors": "{{num}} {[plural(num) one: neimenovan avtor, plural(num) two: neimenovana avtorja, plural(num) few: neimenovani avtorji, other: neimenovanih avtorjev ]}", - "pad.savedrevs.marked": "Ta predelava je označena kot shranjena predelava.", - "pad.savedrevs.timeslider": "Shranjene revizije si lahko ogledate s pomočjo časovnega traku", - "pad.userlist.entername": "Vpišite ime", + "pad.savedrevs.marked": "Ta redakcija je zdaj označena kot shranjena redakcija", + "pad.savedrevs.timeslider": "Shranjene redakcije si lahko ogledate s pomočjo časovnega traku", + "pad.userlist.entername": "Vnesite svoje ime", "pad.userlist.unnamed": "neimenovana oseba", "pad.userlist.guest": "Gost", "pad.userlist.deny": "Zavrni", @@ -122,10 +125,10 @@ "pad.impexp.importbutton": "Uvozi takoj", "pad.impexp.importing": "Poteka uvažanje ...", "pad.impexp.confirmimport": "Uvoz datoteke prepiše obstoječe besedilo dokumenta. Ali ste prepričani, da želite nadaljevati?", - "pad.impexp.convertFailed": "Datoteke ni mogoče uvoziti. Uporabiti je treba enega izmed podprtih zapisov dokumentov ali pa vsebino prilepiti ročno.", + "pad.impexp.convertFailed": "Datoteke ni bilo mogoče uvoziti. Prosimo uporabite drug podprt zapis dokumenta ali pa vsebino prilepite ročno", "pad.impexp.padHasData": "Nismo mogli uvoziti datoteke, ker dokument že vsebuje spremembe. Prosimo, uvozite datoteko v nov dokument", - "pad.impexp.uploadFailed": "Nalaganje je spodletelo, poskusite znova.", - "pad.impexp.importfailed": "Uvoz je spodletel.", - "pad.impexp.copypaste": "Vsebino kopirajte in prilepite.", + "pad.impexp.uploadFailed": "Nalaganje je spodletelo, prosimo poskusite znova", + "pad.impexp.importfailed": "Uvoz je spodletel", + "pad.impexp.copypaste": "Vsebino kopirajte in prilepite", "pad.impexp.exportdisabled": "Izvoz v zapis {{type}} je onemogočen. Za več podrobnosti stopite v stik s skrbnikom." } diff --git a/src/locales/sq.json b/src/locales/sq.json index d6d959ee..28485b33 100644 --- a/src/locales/sq.json +++ b/src/locales/sq.json @@ -5,7 +5,7 @@ "Kosovastar" ] }, - "index.newPad": "Bllok i Ri", + "index.newPad": "Bllok i ri", "index.createOpenPad": "ose krijoni/hapni një Bllok me emrin:", "pad.toolbar.bold.title": "Të trasha (Ctrl-B)", "pad.toolbar.italic.title": "Të pjerrëta (Ctrl-I)", @@ -20,7 +20,7 @@ "pad.toolbar.clearAuthorship.title": "Hiqu Ngjyra Autorësish (Ctrl+Shift+C)", "pad.toolbar.import_export.title": "Importoni/Eksportoni nga/në formate të tjera kartelash", "pad.toolbar.timeslider.title": "Rrjedha kohore", - "pad.toolbar.savedRevision.title": "Ruaje Rishikimin", + "pad.toolbar.savedRevision.title": "Ruaje rishikimin", "pad.toolbar.settings.title": "Rregullime", "pad.toolbar.embed.title": "Ndajeni me të tjerët dhe Trupëzojeni këtë bllok", "pad.toolbar.showusers.title": "Shfaq përdoruesit në këtë bllok", @@ -88,7 +88,7 @@ "timeslider.pageTitle": "Rrjedhë kohore e {{appTitle}}", "timeslider.toolbar.returnbutton": "Rikthehuni te blloku", "timeslider.toolbar.authors": "Autorë:", - "timeslider.toolbar.authorsList": "S’ka Autorë", + "timeslider.toolbar.authorsList": "S’ka autorë", "timeslider.toolbar.exportlink.title": "Eksportoje", "timeslider.exportCurrent": "Eksportojeni versionin e tanishëm si:", "timeslider.version": "Versioni {{version}}", diff --git a/src/locales/sr-ec.json b/src/locales/sr-ec.json index 3d69d52f..de413722 100644 --- a/src/locales/sr-ec.json +++ b/src/locales/sr-ec.json @@ -4,7 +4,8 @@ "Aktron", "Milicevic01", "Милан Јелисавчић", - "Srdjan m" + "Srdjan m", + "Obsuser" ] }, "index.newPad": "Нови Пад", @@ -59,6 +60,8 @@ "pad.modals.connected": "Повезано.", "pad.modals.reconnecting": "Поново се повезујем на ваш пад..", "pad.modals.forcereconnect": "Присилно се поново повежи", + "pad.modals.reconnecttimer": "Покушавам се поново повезати", + "pad.modals.cancel": "Откажи", "pad.modals.userdup": "Отворено у другом прозору", "pad.modals.userdup.explanation": "Изгледа да је овај пад отворен у два или више прозора на овом рачунару.", "pad.modals.userdup.advice": "Поново се повежите на овој прозор.", diff --git a/src/locales/sv.json b/src/locales/sv.json index 44df4506..e73c3e7f 100644 --- a/src/locales/sv.json +++ b/src/locales/sv.json @@ -54,10 +54,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "Du kan endast importera från oformaterad text eller HTML-format. För mer avancerade importeringsfunktioner, var god <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">installera abiword</a>.", + "pad.importExport.abiword.innerHTML": "Du kan endast importera från oformaterad text eller HTML-format. För mer avancerade importfunktioner, var god <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">installera AbiWord</a>.", "pad.modals.connected": "Ansluten.", "pad.modals.reconnecting": "Återansluter till ditt block...", "pad.modals.forcereconnect": "Tvinga återanslutning", + "pad.modals.reconnecttimer": "Försöker ansluta igen", + "pad.modals.cancel": "Avbryt", "pad.modals.userdup": "Öppnades i ett nytt fönster", "pad.modals.userdup.explanation": "Detta block verkar vara öppet i mer än ett fönster på denna dator.", "pad.modals.userdup.advice": "Återanslut för att använda detta fönster istället.", diff --git a/src/locales/ta.json b/src/locales/ta.json new file mode 100644 index 00000000..c0a7cdc0 --- /dev/null +++ b/src/locales/ta.json @@ -0,0 +1,77 @@ +{ + "@metadata": { + "authors": [ + "Balajijagadesh", + "ElangoRamanujam", + "Sank" + ] + }, + "index.newPad": "புதிய அட்டை", + "index.createOpenPad": "அல்லது பெயருடன் ஒரு அட்டையை உருவாக்கு/திற", + "pad.toolbar.bold.title": "தடித்த (Ctrl+B)", + "pad.toolbar.italic.title": "சாய்ந்த (Ctrl+l)", + "pad.toolbar.underline.title": "அடிக்கோடு (Ctrl-U)", + "pad.toolbar.strikethrough.title": "குறுக்குக்கோடு (Ctrl+5)", + "pad.toolbar.timeslider.title": "நேர வழுக்கி", + "pad.toolbar.settings.title": "அமைப்புகள்", + "pad.toolbar.embed.title": "இவ்வட்டையை பகிர் மற்றும் பதி", + "pad.toolbar.showusers.title": "இவ்வட்டையின் பயனர்களை காட்டவும்", + "pad.colorpicker.save": "சேமி", + "pad.colorpicker.cancel": "இரத்து செய்", + "pad.loading": "ஏற்றப்படுகிறது...", + "pad.passwordRequired": "இவ்வட்டையை அணுக தங்களுக்கு ஒரு கடவுச்சொல் தேவைப்படும்", + "pad.permissionDenied": "இவ்வட்டையை அணுக தங்களுக்கு அனுமதி இல்லை", + "pad.wrongPassword": "தங்கள் கடவுச்சொல் தவறானது", + "pad.settings.padSettings": "அட்டை அமைவுகள்", + "pad.settings.myView": "என் பார்வை", + "pad.settings.stickychat": "திரையில் எப்பொழுதும் அரட்டை", + "pad.settings.chatandusers": "அரட்டை மற்றும் பயனர்களை காட்டுக", + "pad.settings.colorcheck": "ஆசிரியர் நிறங்கள்", + "pad.settings.linenocheck": "வரி எண்கள்", + "pad.settings.fontType": "எழுத்துரு வகை:", + "pad.settings.globalView": "உலக பார்வை", + "pad.settings.language": "மொழி:", + "pad.importExport.import_export": "இறக்குமதி/ஏற்றுமதி", + "pad.importExport.importSuccessful": "வெற்றி!", + "pad.modals.connected": "இணைக்கப்பட்டது.", + "pad.modals.initsocketfail": "வழங்கியை தொடர்பு கொள்ளமுடியவில்லை", + "pad.modals.deleted": "நீக்கப்பட்டது", + "pad.modals.deleted.explanation": "இந்த அட்டை நீக்கப்பட்டது.", + "pad.modals.disconnected": "தாங்கள் துண்டிக்கப்பட்டுள்ளீர்கள்", + "pad.modals.disconnected.explanation": "வழங்கியின் தொடர்பு தொலைந்து", + "pad.share": "இவ்வட்டையை பகிர்க", + "pad.share.readonly": "வாசிக்க மாத்திரம்", + "pad.share.link": "இணைப்பு", + "pad.share.emebdcode": "உரலியை பதிக", + "pad.chat": "அரட்டை", + "pad.chat.title": "இவ்வட்டைக்கு அரட்டையை திறக்கவும்", + "pad.chat.loadmessages": "மேலும் தகவல்களை பதிவேற்றவும்", + "timeslider.pageTitle": "{{appTitle}} நேரவழுக்கி", + "timeslider.toolbar.returnbutton": "அட்டைக்கு திரும்பவும்", + "timeslider.toolbar.authors": "ஆசிரியர்கள்:", + "timeslider.toolbar.authorsList": "ஆசிரியர்கள் இல்லை", + "timeslider.toolbar.exportlink.title": "ஏற்றுமதி செய்க", + "timeslider.version": "பதிப்பு {{version}}", + "timeslider.month.january": "சனவரி", + "timeslider.month.february": "பெப்ரவரி", + "timeslider.month.march": "மார்ச்", + "timeslider.month.april": "ஏப்ரல்", + "timeslider.month.may": "மே", + "timeslider.month.june": "சூன்", + "timeslider.month.july": "சூலை", + "timeslider.month.august": "ஆகஸ்ட்", + "timeslider.month.september": "செப்டம்பர்", + "timeslider.month.october": "அக்டோபர்", + "timeslider.month.november": "நவம்பர்", + "timeslider.month.december": "டிசம்பர்", + "pad.userlist.entername": "உங்கள் பெயரை உள்ளிடுக", + "pad.userlist.unnamed": "பெயரிடப்படாதது", + "pad.userlist.guest": "விருந்தினர்", + "pad.userlist.deny": "மறுக்கவும்", + "pad.userlist.approve": "ஒப்புதல் அளிக்கவும்", + "pad.impexp.importbutton": "இப்பொழுது இறக்குக", + "pad.impexp.importing": "இறக்குகிறது...", + "pad.impexp.uploadFailed": "பதிவேற்றம் தோல்வியடைந்தது, தயவுசெய்து மீண்டும் முயலவும்.", + "pad.impexp.importfailed": "இறக்குமதி தோல்வியடைந்தது", + "pad.impexp.copypaste": "படியெடுத்து ஒட்டுக" +} diff --git a/src/locales/te.json b/src/locales/te.json index 19878206..846ced8e 100644 --- a/src/locales/te.json +++ b/src/locales/te.json @@ -14,7 +14,7 @@ "pad.toolbar.bold.title": "మందం", "pad.toolbar.italic.title": "వాలు అక్షరాలు", "pad.toolbar.underline.title": "క్రిందగీత", - "pad.toolbar.strikethrough.title": "కొట్టివేత", + "pad.toolbar.strikethrough.title": "కొట్టివేత (Ctrl+5)", "pad.toolbar.ol.title": "నిర్ధేశింపబడిన జాబితా", "pad.toolbar.ul.title": "అనిర్దేశిత జాబితా, ( క్రమపద్ధతి లేని జాబితా )", "pad.toolbar.undo.title": "చేయవద్దు", diff --git a/src/locales/tr.json b/src/locales/tr.json index bed5c6ec..0be2588f 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -6,7 +6,8 @@ "Joseph", "Meelo", "Trockya", - "McAang" + "McAang", + "Vito Genovese" ] }, "index.newPad": "Yeni Bloknot", @@ -37,7 +38,7 @@ "pad.wrongPassword": "Parolanız yanlış", "pad.settings.padSettings": "Bloknot Ayarları", "pad.settings.myView": "Görünümüm", - "pad.settings.stickychat": "Ekranda her zaman sohbet edin", + "pad.settings.stickychat": "Sohbeti her zaman ekranda yap", "pad.settings.chatandusers": "Sohbeti ve Kullanıcıları Göster", "pad.settings.colorcheck": "Yazarlık renkleri", "pad.settings.linenocheck": "Satır numaraları", @@ -57,10 +58,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Açık Doküman Biçimi)", - "pad.importExport.abiword.innerHTML": "Yalnızca düz metin ya da HTML biçimlerini içe aktarabilirsiniz. Daha fazla gelişmiş içe aktarım özellikleri için <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">AbiWord'ü yükleyin</a>.", + "pad.importExport.abiword.innerHTML": "Yalnızca düz metin ya da HTML biçimlerini içe aktarabilirsiniz. Daha fazla gelişmiş içe aktarım özellikleri için lütfen <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">AbiWord'ü yükleyin</a>.", "pad.modals.connected": "Bağlandı.", "pad.modals.reconnecting": "Bloknotunuza tekrar bağlanılıyor...", "pad.modals.forcereconnect": "Yeniden bağlanmaya zorla", + "pad.modals.reconnecttimer": "Yeniden bağlanmaya çalışılıyor", + "pad.modals.cancel": "İptal", "pad.modals.userdup": "Başka pencerede açıldı", "pad.modals.userdup.explanation": "Bu bloknot bu bilgisayarda birden fazla tarayıcı penceresinde açılmış gibi görünüyor.", "pad.modals.userdup.advice": "Bu pencereden kullanmak için yeniden bağlanın.", @@ -100,7 +103,7 @@ "timeslider.playPause": "Bloknot İçeriğini Oynat / Durdur", "timeslider.backRevision": "Bu bloknottaki bir revizyona geri git", "timeslider.forwardRevision": "Bu bloknatta sonraki revizyona git", - "timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}.{{minutes}}.{{seconds}}", + "timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}", "timeslider.month.january": "Ocak", "timeslider.month.february": "Şubat", "timeslider.month.march": "Mart", @@ -113,11 +116,11 @@ "timeslider.month.october": "Ekim", "timeslider.month.november": "Kasım", "timeslider.month.december": "Aralık", - "timeslider.unnamedauthors": "{{num}} adsız {[plural(num) one: yazar, other: yazar ]}", + "timeslider.unnamedauthors": "{{num}} isimsiz {[plural(num) one: yazar, other: yazar ]}", "pad.savedrevs.marked": "Bu düzenleme artık kayıtlı bir düzeltme olarak işaretlendi", "pad.savedrevs.timeslider": "Zaman kaydırıcısını ziyaret ederek kaydedilen revizyonları görebilirsiniz", "pad.userlist.entername": "Adınızı girin", - "pad.userlist.unnamed": "Adlandırılmamış", + "pad.userlist.unnamed": "isimsiz", "pad.userlist.guest": "Misafir", "pad.userlist.deny": "Reddet", "pad.userlist.approve": "Onayla", diff --git a/src/locales/uk.json b/src/locales/uk.json index d5384a55..9f89e502 100644 --- a/src/locales/uk.json +++ b/src/locales/uk.json @@ -7,7 +7,9 @@ "Steve.rusyn", "SteveR", "Lxlalexlxl", - "Григорій Пугач" + "Григорій Пугач", + "Bunyk", + "Piramidion" ] }, "index.newPad": "Створити", @@ -62,6 +64,8 @@ "pad.modals.connected": "З'єднано.", "pad.modals.reconnecting": "Перепідлючення до Вашого документу..", "pad.modals.forcereconnect": "Примусове перепідключення", + "pad.modals.reconnecttimer": "Триває спроба відновлення з'єднання", + "pad.modals.cancel": "Скасувати", "pad.modals.userdup": "Відкрито в іншому вікні", "pad.modals.userdup.explanation": "Документ, можливо, відкрито більш ніж в одному вікні браузера на цьому комп'ютері.", "pad.modals.userdup.advice": "Перепідключитись використовуючи це вікно.", diff --git a/src/locales/zh-hans.json b/src/locales/zh-hans.json index b4ff306f..a598d9aa 100644 --- a/src/locales/zh-hans.json +++ b/src/locales/zh-hans.json @@ -62,10 +62,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF(开放文档格式)", - "pad.importExport.abiword.innerHTML": "您只能导入纯文本或HTML格式。<a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">安裝abiword</a>取得更多高级的导入功能。", + "pad.importExport.abiword.innerHTML": "您只可以导入纯文本或HTML格式。要获取更高级的导入功能,请<a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">安装AbiWord</a>。", "pad.modals.connected": "已连接。", "pad.modals.reconnecting": "重新连接到您的记事本...", "pad.modals.forcereconnect": "强制重新连接", + "pad.modals.reconnecttimer": "尝试重新连入", + "pad.modals.cancel": "取消", "pad.modals.userdup": "在另一个窗口中打开", "pad.modals.userdup.explanation": "此记事本似乎在本电脑上的多个浏览器窗口中打开。", "pad.modals.userdup.advice": "重新连接,使用此窗口。", diff --git a/src/locales/zh-hant.json b/src/locales/zh-hant.json index a66ec416..e9cac9d4 100644 --- a/src/locales/zh-hant.json +++ b/src/locales/zh-hant.json @@ -11,8 +11,8 @@ "Kly" ] }, - "index.newPad": "新Pad", - "index.createOpenPad": "或創建/開啟以下名稱的pad:", + "index.newPad": "新記事本", + "index.createOpenPad": "或創建/開啟以下名稱的記事本:", "pad.toolbar.bold.title": "粗體(Ctrl-B)", "pad.toolbar.italic.title": "斜體(Ctrl-I)", "pad.toolbar.underline.title": "底線(Ctrl-U)", @@ -28,16 +28,16 @@ "pad.toolbar.timeslider.title": "時間軸", "pad.toolbar.savedRevision.title": "儲存修訂", "pad.toolbar.settings.title": "設定", - "pad.toolbar.embed.title": "分享和嵌入此pad", - "pad.toolbar.showusers.title": "顯示此 pad 的使用者", + "pad.toolbar.embed.title": "分享和嵌入此記事本", + "pad.toolbar.showusers.title": "顯示此記事本的使用者", "pad.colorpicker.save": "儲存", "pad.colorpicker.cancel": "取消", "pad.loading": "載入中...", "pad.noCookie": "找不到 Cookie。請讓你的瀏覽器允許 Cookie!", - "pad.passwordRequired": "您需要密碼才能訪問這個pad", - "pad.permissionDenied": "你沒有訪問這個pad的權限", + "pad.passwordRequired": "您需要密碼才能訪問這個記事本", + "pad.permissionDenied": "你沒有訪問這個記事本的權限", "pad.wrongPassword": "密碼錯誤", - "pad.settings.padSettings": "Pad設定", + "pad.settings.padSettings": "記事本設定", "pad.settings.myView": "我的視窗", "pad.settings.stickychat": "永遠在屏幕上顯示聊天", "pad.settings.chatandusers": "顯示聊天與使用者", @@ -52,7 +52,7 @@ "pad.importExport.import_export": "匯入/匯出", "pad.importExport.import": "上載任何文字檔或文件", "pad.importExport.importSuccessful": "完成!", - "pad.importExport.export": "匯出當前pad為:", + "pad.importExport.export": "匯出目前的記事本為:", "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "純文字", @@ -61,10 +61,12 @@ "pad.importExport.exportopen": "ODF(開放文件格式)", "pad.importExport.abiword.innerHTML": "您只可以純文字或html格式檔匯入。<a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">安裝abiword</a>取得更多進階的匯入功能。", "pad.modals.connected": "已連線。", - "pad.modals.reconnecting": "重新連接到您的pad...", + "pad.modals.reconnecting": "重新連接到您的記事本...", "pad.modals.forcereconnect": "強制重新連線", + "pad.modals.reconnecttimer": "嘗試重新連接在", + "pad.modals.cancel": "取消", "pad.modals.userdup": "在另一個視窗中開啟", - "pad.modals.userdup.explanation": "此pad似乎在此電腦上的多個瀏覽器視窗中開啟。", + "pad.modals.userdup.explanation": "此記事本似乎在此電腦上的多個瀏覽器視窗中開啟。", "pad.modals.userdup.advice": "重新連接到此視窗。", "pad.modals.unauth": "未授權", "pad.modals.unauth.explanation": "您的權限在查看此頁時發生更改。請嘗試重新連接。", @@ -77,40 +79,40 @@ "pad.modals.slowcommit.cause": "這可能是因為網路連線問題所造成。", "pad.modals.badChangeset.explanation": "您的一個編輯被同步伺服器類為非法。", "pad.modals.badChangeset.cause": "這可能由於伺服器的配置錯誤或遇到意外問題。若您認為這是錯誤,請聯繫伺服器管理員。如要繼續編輯,請嘗試重新連接。", - "pad.modals.corruptPad.explanation": "您試圖存取的平板已損壞。", + "pad.modals.corruptPad.explanation": "您試圖存取的記事本已損壞。", "pad.modals.corruptPad.cause": "這可能由於伺服器的配置錯誤或遇到意外問題。請聯繫伺服器管理員。", "pad.modals.deleted": "已刪除。", - "pad.modals.deleted.explanation": "此pad已被移除。", + "pad.modals.deleted.explanation": "此記事本已被移除。", "pad.modals.disconnected": "您已中斷連線。", "pad.modals.disconnected.explanation": "伺服器連接曾中斷", "pad.modals.disconnected.cause": "伺服器可能無法使用。若此情況持續發生,請通知伺服器管理員。", - "pad.share": "分享此pad", + "pad.share": "分享此記事本", "pad.share.readonly": "唯讀", "pad.share.link": "連結", "pad.share.emebdcode": "嵌入網址", "pad.chat": "聊天功能", - "pad.chat.title": "打開pad聊天功能", + "pad.chat.title": "打開記事本聊天功能", "pad.chat.loadmessages": "載入更多訊息", "timeslider.pageTitle": "{{appTitle}}時間軸", - "timeslider.toolbar.returnbutton": "返回到pad", + "timeslider.toolbar.returnbutton": "返回到記事本", "timeslider.toolbar.authors": "協作者:", "timeslider.toolbar.authorsList": "無協作者", "timeslider.toolbar.exportlink.title": "匯出", "timeslider.exportCurrent": "匯出當前版本為:", "timeslider.version": "版本{{version}}", "timeslider.saved": "{{year}}年{{month}}{{day}}日儲存", - "timeslider.playPause": "放送 / 暫停Pad內容", - "timeslider.backRevision": "返回此Pad的前一次修訂", - "timeslider.forwardRevision": "前往此Pad的前一次修訂", + "timeslider.playPause": "放送 / 暫停記事本內容", + "timeslider.backRevision": "返回此記事本的前一次修訂", + "timeslider.forwardRevision": "前往此記事本的前一次修訂", "timeslider.dateformat": "{{year}}年{{month}}月{{day}}日 {{hours}}:{{minutes}}:{{seconds}}", "timeslider.month.january": "1月", - "timeslider.month.february": "二月", + "timeslider.month.february": "2月", "timeslider.month.march": "3月", "timeslider.month.april": "4月", "timeslider.month.may": "5月", "timeslider.month.june": "6月", "timeslider.month.july": "7月", - "timeslider.month.august": "八月", + "timeslider.month.august": "8月", "timeslider.month.september": "9月", "timeslider.month.october": "10月", "timeslider.month.november": "11月", @@ -126,9 +128,9 @@ "pad.editbar.clearcolors": "清除整個文檔的協作者顏色區別嗎?", "pad.impexp.importbutton": "現在匯入", "pad.impexp.importing": "匯入中...", - "pad.impexp.confirmimport": "匯入的檔案將會覆蓋pad內目前的文字。您確定要繼續嗎?", + "pad.impexp.confirmimport": "匯入的檔案將會覆蓋記事本內目前的文字。您確定要繼續嗎?", "pad.impexp.convertFailed": "未能匯入此檔案。請以其他檔案格式或手動複製貼上匯入。", - "pad.impexp.padHasData": "此Pad已異動過所以無法匯入該檔案,請匯入至另一個Pad試試。", + "pad.impexp.padHasData": "此記事本已異動過所以無法匯入該檔案,請匯入至另一個記事本試試。", "pad.impexp.uploadFailed": "上載失敗,請重試", "pad.impexp.importfailed": "匯入失敗", "pad.impexp.copypaste": "請複製貼上", diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index 5d26f470..d44cb7b3 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -592,6 +592,11 @@ Pad.prototype.copy = function copy(destinationID, force, callback) { setTimeout(function(){ padManager.getPad(destinationID, null, callback) // this runs too early. },10); + }, + // let the plugins know the pad was copied + function(callback) { + hooks.callAll('padCopy', { 'originalPad': _this, 'destinationID': destinationID }); + callback(); } // series ], function(err) diff --git a/src/node/db/SecurityManager.js b/src/node/db/SecurityManager.js index 6fae57ff..bbd8cef4 100644 --- a/src/node/db/SecurityManager.js +++ b/src/node/db/SecurityManager.js @@ -31,7 +31,7 @@ var authLogger = log4js.getLogger("auth"); /** * This function controlls the access to a pad, it checks if the user can access a pad. * @param padID the pad the user wants to access - * @param sesssionID the session the user has (set via api) + * @param sessionCookie the session the user has (set via api) * @param token the token of the author (randomly generated at client side, used for public pads) * @param password the password the user has given to access this pad, can be null * @param callback will be called with (err, {accessStatus: grant|deny|wrongPassword|needPassword, authorID: a.xxxxxx}) diff --git a/src/node/handler/ImportHandler.js b/src/node/handler/ImportHandler.js index 870c954a..6aa94e64 100644 --- a/src/node/handler/ImportHandler.js +++ b/src/node/handler/ImportHandler.js @@ -56,10 +56,14 @@ exports.doImport = function(req, res, padId) , pad , text , importHandledByPlugin - , directDatabaseAccess; + , directDatabaseAccess + , useAbiword; var randNum = Math.floor(Math.random()*0xFFFFFFFF); + // setting flag for whether to use abiword or not + useAbiword = (abiword != null); + async.series([ //save the uploaded file to /tmp function(callback) { @@ -147,9 +151,9 @@ exports.doImport = function(req, res, padId) var fileEnding = path.extname(srcFile).toLowerCase(); var fileIsHTML = (fileEnding === ".html" || fileEnding === ".htm"); var fileIsTXT = (fileEnding === ".txt"); - if (fileIsTXT) abiword = false; // Don't use abiword for text files + if (fileIsTXT) useAbiword = false; // Don't use abiword for text files // See https://github.com/ether/etherpad-lite/issues/2572 - if (abiword && !fileIsHTML) { + if (useAbiword && !fileIsHTML) { abiword.convertFile(srcFile, destFile, "htm", function(err) { //catch convert errors if(err) { @@ -169,7 +173,7 @@ exports.doImport = function(req, res, padId) }, function(callback) { - if (!abiword && !directDatabaseAccess){ + if (!useAbiword && !directDatabaseAccess){ // Read the file with no encoding for raw buffer access. fs.readFile(destFile, function(err, buf) { if (err) throw err; @@ -228,7 +232,7 @@ exports.doImport = function(req, res, padId) function(callback) { if(!directDatabaseAccess){ var fileEnding = path.extname(srcFile).toLowerCase(); - if (importHandledByPlugin || abiword || fileEnding == ".htm" || fileEnding == ".html") { + if (importHandledByPlugin || useAbiword || fileEnding == ".htm" || fileEnding == ".html") { importHtml.setPadHTML(pad, text, function(e){ if(e) apiLogger.warn("Error importing, possibly caused by malformed HTML"); }); diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 279a44e1..b7ec7cb2 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -936,7 +936,7 @@ function handleSwitchToPad(client, message) var currentSession = sessioninfos[client.id]; var padId = currentSession.padId; var roomClients = _getRoomClients(padId); - + async.forEach(roomClients, function(client, callback) { var sinfo = sessioninfos[client.id]; if(sinfo && sinfo.author == currentSession.author) { @@ -1115,7 +1115,7 @@ function handleClientReady(client, message) //Check if this author is already on the pad, if yes, kick the other sessions! var roomClients = _getRoomClients(pad.id); - + async.forEach(roomClients, function(client, callback) { var sinfo = sessioninfos[client.id]; if(sinfo && sinfo.author == author) { @@ -1176,6 +1176,7 @@ function handleClientReady(client, message) "accountPrivs": { "maxRevisions": 100 }, + "automaticReconnectionTimeout": settings.automaticReconnectionTimeout, "initialRevisionList": [], "initialOptions": { "guestPolicy": "deny" @@ -1196,6 +1197,7 @@ function handleClientReady(client, message) "userColor": authorColorId, "padId": message.padId, "padOptions": settings.padOptions, + "padShortcutEnabled": settings.padShortcutEnabled, "initialTitle": "Pad: " + message.padId, "opts": {}, // tell the client the number of the latest chat-message, which will be @@ -1676,13 +1678,13 @@ function composePadChangesets(padId, startNum, endNum, callback) function _getRoomClients(padID) { var roomClients = []; var room = socketio.sockets.adapter.rooms[padID]; - + if (room) { for (var id in room.sockets) { roomClients.push(socketio.sockets.sockets[id]); } } - + return roomClients; } diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js index c53eb1d1..190021a3 100644 --- a/src/node/hooks/express/webaccess.js +++ b/src/node/hooks/express/webaccess.js @@ -116,7 +116,7 @@ exports.expressConfigure = function (hook_name, args, cb) { if (!exports.sessionStore) { exports.sessionStore = new ueberStore(); - exports.secret = settings.sessionKey; // Isn't this being reset each time the server spawns? + exports.secret = settings.sessionKey; } args.app.sessionStore = exports.sessionStore; diff --git a/src/node/utils/Cli.js b/src/node/utils/Cli.js index 0c7947e9..9419ed26 100644 --- a/src/node/utils/Cli.js +++ b/src/node/utils/Cli.js @@ -34,5 +34,10 @@ for ( var i = 0; i < argv.length; i++ ) { exports.argv.settings = arg; } + // Override location of credentials.json file + if ( prevArg == '--credentials' ) { + exports.argv.credentials = arg; + } + prevArg = arg; } diff --git a/src/node/utils/Minify.js b/src/node/utils/Minify.js index 80652310..a56e347d 100644 --- a/src/node/utils/Minify.js +++ b/src/node/utils/Minify.js @@ -23,9 +23,9 @@ var ERR = require("async-stacktrace"); var settings = require('./Settings'); var async = require('async'); var fs = require('fs'); +var StringDecoder = require('string_decoder').StringDecoder; var CleanCSS = require('clean-css'); -var jsp = require("uglify-js").parser; -var pro = require("uglify-js").uglify; +var uglifyJS = require("uglify-js"); var path = require('path'); var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins"); var RequireKernel = require('etherpad-require-kernel'); @@ -400,10 +400,10 @@ function getFile(filename, callback) { function compressJS(content) { - var ast = jsp.parse(content); // parse code and get the initial AST - ast = pro.ast_mangle(ast); // get a new AST with mangled names - ast = pro.ast_squeeze(ast); // get an AST with compression optimizations - return pro.gen_code(ast); // compressed code here + var decoder = new StringDecoder('utf8'); + var code = decoder.write(content); // convert from buffer to string + var codeMinified = uglifyJS.minify(code, {fromString: true}).code; + return codeMinified; } function compressCSS(filename, content, callback) diff --git a/src/node/utils/Settings.js b/src/node/utils/Settings.js index 24bc25c3..660b7afb 100644 --- a/src/node/utils/Settings.js +++ b/src/node/utils/Settings.js @@ -100,7 +100,35 @@ exports.padOptions = { "alwaysShowChat": false, "chatAndUsers": false, "lang": "en-gb" -} +}, + +/** + * Whether certain shortcut keys are enabled for a user in the pad + */ +exports.padShortcutEnabled = { + "altF9" : true, + "altC" : true, + "delete" : true, + "cmdShift2" : true, + "return" : true, + "esc" : true, + "cmdS" : true, + "tab" : true, + "cmdZ" : true, + "cmdY" : true, + "cmdB" : true, + "cmdI" : true, + "cmdU" : true, + "cmd5" : true, + "cmdShiftL" : true, + "cmdShiftN" : true, + "cmdShift1" : true, + "cmdShiftC" : true, + "cmdH" : true, + "ctrlHome" : true, + "pageUp" : true, + "pageDown" : true, +}, /** * The toolbar buttons and order. @@ -178,6 +206,11 @@ exports.loglevel = "INFO"; exports.disableIPlogging = false; /** + * Number of seconds to automatically reconnect pad + */ +exports.automaticReconnectionTimeout = 0; + +/** * Disable Load Testing */ exports.loadTest = false; diff --git a/src/package.json b/src/package.json index ca86258f..a182fd97 100644 --- a/src/package.json +++ b/src/package.json @@ -13,10 +13,10 @@ ], "dependencies" : { "etherpad-yajsml" : "0.0.2", - "request" : "2.55.0", + "request" : "2.83.0", "etherpad-require-kernel" : "1.0.9", "resolve" : "1.1.7", - "socket.io" : "1.6.0", + "socket.io" : "1.7.3", "ueberdb2" : "0.3.0", "express" : "4.13.4", "express-session" : "1.13.0", @@ -55,6 +55,6 @@ "repository" : { "type" : "git", "url" : "http://github.com/ether/etherpad-lite.git" }, - "version" : "1.6.1", + "version" : "1.6.2", "license" : "Apache-2.0" } diff --git a/src/static/css/pad.css b/src/static/css/pad.css index 5764c5e4..cabde7ef 100644 --- a/src/static/css/pad.css +++ b/src/static/css/pad.css @@ -517,6 +517,23 @@ table#otheruserstable { display: block; } +/* styles for the automatic reconnection timer: */ +#connectivity .visible.with_reconnect_timer button, +#connectivity .visible.with_reconnect_timer .reconnecttimer * { + display: inline-block; +} + +#connectivity .with_reconnect_timer .hidden, +#connectivity .with_reconnect_timer #defaulttext.hidden, +#connectivity .with_reconnect_timer button.hidden { + display: none; +} + +#connectivity .with_reconnect_timer #cancelreconnect { + margin-left: 10px; +} +/* end of styles for the automatic reconnection timer */ + #reconnect_form button { font-size: 12pt; padding: 5px; @@ -1255,11 +1272,41 @@ input[type=checkbox] { } /* End of gritter stuff */ +/* Montserrat Font */ +@font-face { + font-family: "Montserrat"; + src: url("../../static/font/Montserrat-Light.otf") format("opentype"); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: "Montserrat"; + src: url("../../static/font/Montserrat-Regular.otf") format("opentype"); + font-weight: bold; + font-style: normal; +} +/* End of Monterrat Font */ + @font-face { font-family: opendyslexic; src: url("../../static/font/opendyslexic.otf") format("opentype"); } +/* Roboto Mono */ +@font-face { + font-family: "RobotoMono"; + src: url("../../static/font/RobotoMono-Regular.ttf") format("truetype"); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: "RobotoMono"; + src: url("../../static/font/RobotoMono-Bold.ttf") format("truetype"); + font-weight: bold; + font-style: normal; +} +/* End of Roboto Mono */ + @font-face { font-family: "fontawesome-etherpad"; src:url("../../static/font/fontawesome-etherpad.eot"); @@ -1304,5 +1351,3 @@ input[type=checkbox] { .hideControlsEditbar{ display:none !important; } - - diff --git a/src/static/font/Montserrat-Light.otf b/src/static/font/Montserrat-Light.otf Binary files differnew file mode 100755 index 00000000..f2f0e2df --- /dev/null +++ b/src/static/font/Montserrat-Light.otf diff --git a/src/static/font/Montserrat-Regular.otf b/src/static/font/Montserrat-Regular.otf Binary files differnew file mode 100755 index 00000000..f61d57ec --- /dev/null +++ b/src/static/font/Montserrat-Regular.otf diff --git a/src/static/font/RobotoMono-Bold.ttf b/src/static/font/RobotoMono-Bold.ttf Binary files differnew file mode 100755 index 00000000..07ef607d --- /dev/null +++ b/src/static/font/RobotoMono-Bold.ttf diff --git a/src/static/font/RobotoMono-Regular.ttf b/src/static/font/RobotoMono-Regular.ttf Binary files differnew file mode 100755 index 00000000..b158a334 --- /dev/null +++ b/src/static/font/RobotoMono-Regular.ttf diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 0970666e..424bacf5 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -1782,9 +1782,9 @@ function Ace2Inner(){ return !!STYLE_ATTRIBS[aname]; } - function isIncorpedAttribute(aname) + function isOtherIncorpedAttribute(aname) { - return ( !! STYLE_ATTRIBS[aname]) || ( !! OTHER_INCORPED_ATTRIBS[aname]); + return !!OTHER_INCORPED_ATTRIBS[aname]; } function insertDomLines(nodeToAddAfter, infoStructs, isTimeUp) @@ -2526,7 +2526,6 @@ function Ace2Inner(){ function doIncorpLineSplice(startLine, deleteCount, newLineEntries, lineAttribs, hints) { - var startOldChar = rep.lines.offsetOfIndex(startLine); var endOldChar = rep.lines.offsetOfIndex(startLine + deleteCount); @@ -2760,7 +2759,7 @@ function Ace2Inner(){ { function incorpedAttribFilter(anum) { - return isStyleAttribute(rep.apool.getAttribKey(anum)); + return !isOtherIncorpedAttribute(rep.apool.getAttribKey(anum)); } function attribRuns(attribs) @@ -3368,7 +3367,12 @@ function Ace2Inner(){ evt.preventDefault(); } } - //hide the dropdownso + + hideEditBarDropdowns(); + } + + function hideEditBarDropdowns() + { if(window.parent.parent.padeditbar){ // required in case its in an iframe should probably use parent.. See Issue 327 https://github.com/ether/etherpad-lite/issues/327 window.parent.parent.padeditbar.toggleDropDown("none"); } @@ -3724,7 +3728,8 @@ function Ace2Inner(){ specialHandled = _.contains(specialHandledInHook, true); } - if ((!specialHandled) && altKey && isTypeForSpecialKey && keyCode == 120){ + var padShortcutEnabled = parent.parent.clientVars.padShortcutEnabled; + if ((!specialHandled) && altKey && isTypeForSpecialKey && keyCode == 120 && padShortcutEnabled.altF9){ // Alt F9 focuses on the File Menu and/or editbar. // Note that while most editors use Alt F10 this is not desirable // As ubuntu cannot use Alt F10.... @@ -3734,14 +3739,14 @@ function Ace2Inner(){ firstEditbarElement.focus(); evt.preventDefault(); } - if ((!specialHandled) && altKey && keyCode == 67 && type === "keydown"){ + if ((!specialHandled) && altKey && keyCode == 67 && type === "keydown" && padShortcutEnabled.altC){ // Alt c focuses on the Chat window $(this).blur(); parent.parent.chat.show(); parent.parent.$("#chatinput").focus(); evt.preventDefault(); } - if ((!specialHandled) && evt.ctrlKey && shiftKey && keyCode == 50 && type === "keydown"){ + if ((!specialHandled) && evt.ctrlKey && shiftKey && keyCode == 50 && type === "keydown" && padShortcutEnabled.cmdShift2){ // Control-Shift-2 shows a gritter popup showing a line author var lineNumber = rep.selEnd[0]; var alineAttrs = rep.alines[lineNumber]; @@ -3819,7 +3824,7 @@ function Ace2Inner(){ time: '4000' }); } - if ((!specialHandled) && isTypeForSpecialKey && keyCode == 8) + if ((!specialHandled) && isTypeForSpecialKey && keyCode == 8 && padShortcutEnabled.delete) { // "delete" key; in mozilla, if we're at the beginning of a line, normalize now, // or else deleting a blank line can take two delete presses. @@ -3833,7 +3838,7 @@ function Ace2Inner(){ doDeleteKey(evt); specialHandled = true; } - if ((!specialHandled) && isTypeForSpecialKey && keyCode == 13) + if ((!specialHandled) && isTypeForSpecialKey && keyCode == 13 && padShortcutEnabled.return) { // return key, handle specially; // note that in mozilla we need to do an incorporation for proper return behavior anyway. @@ -3847,7 +3852,7 @@ function Ace2Inner(){ }, 0); specialHandled = true; } - if ((!specialHandled) && isTypeForSpecialKey && keyCode == 27) + if ((!specialHandled) && isTypeForSpecialKey && keyCode == 27 && padShortcutEnabled.esc) { // prevent esc key; // in mozilla versions 14-19 avoid reconnecting pad. @@ -3856,7 +3861,7 @@ function Ace2Inner(){ evt.preventDefault(); specialHandled = true; } - if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "s" && (evt.metaKey || evt.ctrlKey) && !evt.altKey) /* Do a saved revision on ctrl S */ + if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "s" && (evt.metaKey || evt.ctrlKey) && !evt.altKey && padShortcutEnabled.cmdS) /* Do a saved revision on ctrl S */ { evt.preventDefault(); var originalBackground = parent.parent.$('#revisionlink').css("background") @@ -3867,7 +3872,7 @@ function Ace2Inner(){ parent.parent.pad.collabClient.sendMessage({"type":"SAVE_REVISION"}); /* The parent.parent part of this is BAD and I feel bad.. It may break something */ specialHandled = true; } - if ((!specialHandled) && isTypeForSpecialKey && keyCode == 9 && !(evt.metaKey || evt.ctrlKey)) + if ((!specialHandled) && isTypeForSpecialKey && keyCode == 9 && !(evt.metaKey || evt.ctrlKey) && padShortcutEnabled.tab) { // tab fastIncorp(5); @@ -3876,7 +3881,7 @@ function Ace2Inner(){ //scrollSelectionIntoView(); specialHandled = true; } - if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "z" && (evt.metaKey || evt.ctrlKey) && !evt.altKey) + if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "z" && (evt.metaKey || evt.ctrlKey) && !evt.altKey && padShortcutEnabled.cmdZ) { // cmd-Z (undo) fastIncorp(6); @@ -3891,7 +3896,7 @@ function Ace2Inner(){ } specialHandled = true; } - if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "y" && (evt.metaKey || evt.ctrlKey)) + if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "y" && (evt.metaKey || evt.ctrlKey) && padShortcutEnabled.cmdY) { // cmd-Y (redo) fastIncorp(10); @@ -3899,7 +3904,7 @@ function Ace2Inner(){ doUndoRedo("redo"); specialHandled = true; } - if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "b" && (evt.metaKey || evt.ctrlKey)) + if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "b" && (evt.metaKey || evt.ctrlKey) && padShortcutEnabled.cmdB) { // cmd-B (bold) fastIncorp(13); @@ -3907,7 +3912,7 @@ function Ace2Inner(){ toggleAttributeOnSelection('bold'); specialHandled = true; } - if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "i" && (evt.metaKey || evt.ctrlKey)) + if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "i" && (evt.metaKey || evt.ctrlKey) && padShortcutEnabled.cmdI) { // cmd-I (italic) fastIncorp(14); @@ -3915,7 +3920,7 @@ function Ace2Inner(){ toggleAttributeOnSelection('italic'); specialHandled = true; } - if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "u" && (evt.metaKey || evt.ctrlKey)) + if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "u" && (evt.metaKey || evt.ctrlKey) && padShortcutEnabled.cmdU) { // cmd-U (underline) fastIncorp(15); @@ -3923,7 +3928,7 @@ function Ace2Inner(){ toggleAttributeOnSelection('underline'); specialHandled = true; } - if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "5" && (evt.metaKey || evt.ctrlKey) && evt.altKey !== true) + if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "5" && (evt.metaKey || evt.ctrlKey) && evt.altKey !== true && padShortcutEnabled.cmd5) { // cmd-5 (strikethrough) fastIncorp(13); @@ -3931,7 +3936,7 @@ function Ace2Inner(){ toggleAttributeOnSelection('strikethrough'); specialHandled = true; } - if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "l" && (evt.metaKey || evt.ctrlKey) && evt.shiftKey) + if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "l" && (evt.metaKey || evt.ctrlKey) && evt.shiftKey && padShortcutEnabled.cmdShiftL) { // cmd-shift-L (unorderedlist) fastIncorp(9); @@ -3939,21 +3944,21 @@ function Ace2Inner(){ doInsertUnorderedList() specialHandled = true; } - if ((!specialHandled) && isTypeForCmdKey && (String.fromCharCode(which).toLowerCase() == "n" || String.fromCharCode(which) == 1) && (evt.metaKey || evt.ctrlKey) && evt.shiftKey) + if ((!specialHandled) && isTypeForCmdKey && ((String.fromCharCode(which).toLowerCase() == "n" && padShortcutEnabled.cmdShiftN) || (String.fromCharCode(which) == 1 && padShortcutEnabled.cmdShift1)) && (evt.metaKey || evt.ctrlKey) && evt.shiftKey) { - // cmd-shift-N (orderedlist) + // cmd-shift-N and cmd-shift-1 (orderedlist) fastIncorp(9); evt.preventDefault(); doInsertOrderedList() specialHandled = true; } - if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "c" && (evt.metaKey || evt.ctrlKey) && evt.shiftKey) { + if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "c" && (evt.metaKey || evt.ctrlKey) && evt.shiftKey && padShortcutEnabled.cmdShiftC) { // cmd-shift-C (clearauthorship) fastIncorp(9); evt.preventDefault(); CMDS.clearauthorship(); } - if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "h" && (evt.ctrlKey)) + if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "h" && (evt.ctrlKey) && padShortcutEnabled.cmdH) { // cmd-H (backspace) fastIncorp(20); @@ -3961,7 +3966,7 @@ function Ace2Inner(){ doDeleteKey(); specialHandled = true; } - if((evt.which == 36 && evt.ctrlKey == true)){ setScrollY(0); } // Control Home send to Y = 0 + if((evt.which == 36 && evt.ctrlKey == true) && padShortcutEnabled.ctrlHome){ setScrollY(0); } // Control Home send to Y = 0 if((evt.which == 33 || evt.which == 34) && type == 'keydown' && !evt.ctrlKey){ evt.preventDefault(); // This is required, browsers will try to do normal default behavior on page up / down and the default behavior SUCKS @@ -3980,12 +3985,12 @@ function Ace2Inner(){ var linesCount = rep.lines.length(); // total count of lines in pad IE 10 var numberOfLinesInViewport = newVisibleLineRange[1] - newVisibleLineRange[0]; // How many lines are in the viewport right now? - if(isPageUp){ + if(isPageUp && padShortcutEnabled.pageUp){ rep.selEnd[0] = rep.selEnd[0] - numberOfLinesInViewport; // move to the bottom line +1 in the viewport (essentially skipping over a page) rep.selStart[0] = rep.selStart[0] - numberOfLinesInViewport; // move to the bottom line +1 in the viewport (essentially skipping over a page) } - if(isPageDown){ // if we hit page down + if(isPageDown && padShortcutEnabled.pageDown){ // if we hit page down if(rep.selEnd[0] >= oldVisibleLineRange[0]){ // If the new viewpoint position is actually further than where we are right now rep.selStart[0] = oldVisibleLineRange[1] -1; // dont go further in the page down than what's visible IE go from 0 to 50 if 50 is visible on screen but dont go below that else we miss content rep.selEnd[0] = oldVisibleLineRange[1] -1; // dont go further in the page down than what's visible IE go from 0 to 50 if 50 is visible on screen but dont go below that else we miss content @@ -4984,6 +4989,8 @@ function Ace2Inner(){ $(document).on("keypress", handleKeyEvent); $(document).on("keyup", handleKeyEvent); $(document).on("click", handleClick); + // dropdowns on edit bar need to be closed on clicks on both pad inner and pad outer + $(outerWin.document).on("click", hideEditBarDropdowns); // Disabled: https://github.com/ether/etherpad-lite/issues/2546 // Will break OL re-numbering: https://github.com/ether/etherpad-lite/pull/2533 // $(document).on("cut", handleCut); diff --git a/src/static/js/html10n.js b/src/static/js/html10n.js index eecbaa0a..8dea84c2 100644 --- a/src/static/js/html10n.js +++ b/src/static/js/html10n.js @@ -21,7 +21,7 @@ * IN THE SOFTWARE. */ window.html10n = (function(window, document, undefined) { - + // fix console (function() { var noop = function() {}; @@ -80,7 +80,7 @@ window.html10n = (function(window, document, undefined) { return -1; } } - + /** * MicroEvent - to make any js object an event emitter (server or browser) */ @@ -116,7 +116,7 @@ window.html10n = (function(window, document, undefined) { destObject[props[i]] = MicroEvent.prototype[props[i]]; } } - + /** * Loader * The loader is responsible for loading @@ -127,7 +127,7 @@ window.html10n = (function(window, document, undefined) { this.cache = {} // file => contents this.langs = {} // lang => strings } - + Loader.prototype.load = function(lang, cb) { if(this.langs[lang]) return cb() @@ -137,22 +137,22 @@ window.html10n = (function(window, document, undefined) { this.fetch(this.resources[i], lang, function(e) { reqs++; if(e) console.warn(e) - + if (reqs < n) return;// Call back once all reqs are completed cb && cb() }) } } } - + Loader.prototype.fetch = function(href, lang, cb) { var that = this - + if (this.cache[href]) { this.parse(lang, href, this.cache[href], cb) return; } - + var xhr = new XMLHttpRequest() xhr.open('GET', href, /*async: */true) if (xhr.overrideMimeType) { @@ -172,7 +172,7 @@ window.html10n = (function(window, document, undefined) { }; xhr.send(null); } - + Loader.prototype.parse = function(lang, currHref, data, cb) { if ('object' != typeof data) { cb(new Error('A file couldn\'t be parsed as json.')) @@ -192,7 +192,7 @@ window.html10n = (function(window, document, undefined) { } if(lang != l) return cb(new Error(msg)) } - + if ('string' == typeof data[lang]) { // Import rule @@ -200,7 +200,7 @@ window.html10n = (function(window, document, undefined) { var importUrl = data[lang] // relative path - if(data[lang].indexOf("http") != 0 && data[lang].indexOf("/") != 0) { + if(data[lang].indexOf("http") != 0 && data[lang].indexOf("/") != 0) { importUrl = currHref+"/../"+data[lang] } @@ -217,20 +217,20 @@ window.html10n = (function(window, document, undefined) { // TODO: Also store accompanying langs cb() } - - + + /** * The html10n object */ - var html10n = + var html10n = { language : null } MicroEvent.mixin(html10n) - + html10n.macros = {} html10n.rtl = ["ar","dv","fa","ha","he","ks","ku","ps","ur","yi"] - + /** * Get rules for plural forms (shared with JetPack), see: * http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html @@ -668,7 +668,7 @@ window.html10n = (function(window, document, undefined) { return str; }; - + /** * Localize a document * @param langs An array of lang codes defining fallbacks @@ -710,7 +710,7 @@ window.html10n = (function(window, document, undefined) { // translate element itself if necessary this.translateNode(translations, element) } - + function asyncForEach(list, iterator, cb) { var i = 0 , n = list.length @@ -721,7 +721,7 @@ window.html10n = (function(window, document, undefined) { cb() }) } - + function getTranslatableChildren(element) { if(!document.querySelectorAll) { if (!element) return [] @@ -735,29 +735,29 @@ window.html10n = (function(window, document, undefined) { } return element.querySelectorAll('*[data-l10n-id]') } - + html10n.get = function(id, args) { var translations = html10n.translations if(!translations) return console.warn('No translations available (yet)') if(!translations[id]) return console.warn('Could not find string '+id) - + // apply macros var str = translations[id] - + str = substMacros(id, str, args) - + // apply args str = substArguments(str, args) - + return str } - + // replace {{arguments}} with their values or the // associated translation string (based on its key) function substArguments(str, args) { var reArgs = /\{\{\s*([a-zA-Z\.]+)\s*\}\}/ , match - + while (match = reArgs.exec(str)) { if (!match || match.length < 2) return str // argument key not found @@ -775,15 +775,15 @@ window.html10n = (function(window, document, undefined) { str = str.substring(0, match.index) + sub + str.substr(match.index + match[0].length) } - + return str } - + // replace {[macros]} with their values function substMacros(key, str, args) { var regex = /\{\[\s*([a-zA-Z]+)\(([a-zA-Z]+)\)((\s*([a-zA-Z]+)\: ?([ a-zA-Z{}]+),?)+)*\s*\]\}/ //.exec('{[ plural(n) other: are {{n}}, one: is ]}') , match - + while(match = regex.exec(str)) { // a macro has been found // Note: at the moment, only one parameter is supported @@ -791,9 +791,9 @@ window.html10n = (function(window, document, undefined) { , paramName = match[2] , optv = match[3] , opts = {} - + if (!(macroName in html10n.macros)) continue - + if(optv) { optv.match(/(?=\s*)([a-zA-Z]+)\: ?([ a-zA-Z{}]+)(?=,?)/g).forEach(function(arg) { var parts = arg.split(':') @@ -802,7 +802,7 @@ window.html10n = (function(window, document, undefined) { opts[name] = value }) } - + var param if (args && paramName in args) { param = args[paramName] @@ -814,10 +814,10 @@ window.html10n = (function(window, document, undefined) { var macro = html10n.macros[macroName] str = str.substr(0, match.index) + macro(key, param, opts) + str.substr(match.index+match[0].length) } - + return str } - + /** * Applies translations to a DOM node (recursive) */ @@ -840,9 +840,9 @@ window.html10n = (function(window, document, undefined) { console.warn('Couldn\'t parse args for '+str.id) } } - + str.str = html10n.get(str.id, str.args) - + // get attribute name to apply str to var prop , index = str.id.lastIndexOf('.') @@ -852,6 +852,7 @@ window.html10n = (function(window, document, undefined) { , "alt": 1 , "textContent": 1 , "value": 1 + , "placeholder": 1 } if (index > 0 && str.id.substr(index + 1) in attrList) { // an attribute has been specified prop = str.id.substr(index + 1) @@ -883,7 +884,7 @@ window.html10n = (function(window, document, undefined) { } } } - + /** * Builds a translation object from a list of langs (loads the necessary translations) * @param langs Array - a list of langs sorted by priority (default langs should go last) @@ -898,11 +899,11 @@ window.html10n = (function(window, document, undefined) { }, function() { var lang langs.reverse() - + // loop through the priority array... for (var i=0, n=langs.length; i < n; i++) { lang = langs[i] - + if(!lang) continue; if(!(lang in that.loader.langs)) {// uh, we don't have this lang availbable.. // then check for related langs @@ -915,13 +916,13 @@ window.html10n = (function(window, document, undefined) { } if(lang != l) continue; } - + // ... and apply all strings of the current lang in the list // to our build object for (var string in that.loader.langs[lang]) { build[string] = that.loader.langs[lang][string] } - + // the last applied lang will be exposed as the // lang the page was translated to that.language = lang @@ -929,7 +930,7 @@ window.html10n = (function(window, document, undefined) { cb(null, build) }) } - + /** * Returns the language that was last applied to the translations hash * thus overriding most of the formerly applied langs @@ -962,7 +963,7 @@ window.html10n = (function(window, document, undefined) { this.loader = new Loader(resources) this.trigger('indexed') } - + if (document.addEventListener) // modern browsers and IE9+ document.addEventListener('DOMContentLoaded', function() { html10n.index() diff --git a/src/static/js/pad.js b/src/static/js/pad.js index c967e461..8fcec23f 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -1,5 +1,5 @@ /** - * This code is mostly from the old Etherpad. Please help us to comment this code. + * This code is mostly from the old Etherpad. Please help us to comment this code. * This helps other people to understand this code better and helps them to improve it. * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED */ @@ -99,15 +99,15 @@ function getParams() setting.callback(value); } } - + // Then URL applied stuff var params = getUrlVars() - + for(var i = 0; i < getParameters.length; i++) { var setting = getParameters[i]; var value = params[setting.name]; - + if(value && (value == setting.checkVal || setting.checkVal == null)) { setting.callback(value); @@ -156,7 +156,7 @@ function sendClientReady(isReconnect, messageType) token = "t." + randomString(); createCookie("token", token, 60); } - + var sessionID = decodeURIComponent(readCookie("sessionID")); var password = readCookie("password"); @@ -169,14 +169,14 @@ function sendClientReady(isReconnect, messageType) "token": token, "protocolVersion": 2 }; - + //this is a reconnect, lets tell the server our revisionnumber if(isReconnect == true) { msg.client_rev=pad.collabClient.getCurrentRevisionNumber(); msg.reconnect=true; } - + socket.json.send(msg); } @@ -203,12 +203,12 @@ function handshake() socket.once('connect', function () { sendClientReady(false); }); - + socket.on('reconnect', function () { pad.collabClient.setChannelState("CONNECTED"); pad.sendClientReady(true); }); - + socket.on('reconnecting', function() { pad.collabClient.setChannelState("RECONNECTING"); }); @@ -254,7 +254,7 @@ function handshake() $("#passwordinput").focus(); } } - + //if we haven't recieved the clientVars yet, then this message should it be else if (!receivedClientVars && obj.type == "CLIENT_VARS") { @@ -267,7 +267,7 @@ function handshake() clientVars = obj.data; clientVars.userAgent = "Anonymous"; clientVars.collab_client_vars.clientAgent = "Anonymous"; - + //initalize the pad pad._afterHandshake(); initalized = true; @@ -298,7 +298,7 @@ function handshake() { pad.changeViewOption('noColors', true); } - + if (settings.rtlIsTrue == true) { pad.changeViewOption('rtlIsTrue', true); @@ -335,6 +335,12 @@ function handshake() console.warn(obj); padconnectionstatus.disconnected(obj.disconnect); socket.disconnect(); + + // block user from making any change to the pad + padeditor.disable(); + padeditbar.disable(); + padimpexp.disable(); + return; } else @@ -345,13 +351,13 @@ function handshake() }); // Bind the colorpicker var fb = $('#colorpicker').farbtastic({ callback: '#mycolorpickerpreview', width: 220}); - // Bind the read only button + // Bind the read only button $('#readonlyinput').on('click',function(){ padeditbar.setEmbedLinks(); }); } -$.extend($.gritter.options, { +$.extend($.gritter.options, { position: 'bottom-right', // defaults to 'top-right' but can be 'bottom-left', 'bottom-right', 'top-left', 'top-right' (added in 1.7.1) fade: false, // dont fade, too jerky on mobile time: 6000 // hang on the screen for... @@ -424,7 +430,7 @@ var pad = { if(window.history && window.history.pushState) { $('#chattext p').remove(); //clear the chat messages - window.history.pushState("", "", newHref); + window.history.pushState("", "", newHref); receivedClientVars = false; sendClientReady(false, 'SWITCH_TO_PAD'); } @@ -453,7 +459,7 @@ var pad = { // This will check if the prefs-cookie is set. // Otherwise it shows up a message to the user. padcookie.init(); - if (!readCookie("prefs")) + if (!padcookie.isCookiesEnabled()) { $('#loading').hide(); $('#noCookie').show(); @@ -548,10 +554,12 @@ var pad = { pad.changeViewOption('rtlIsTrue', true); } - var fonts = ['useMonospaceFont', 'useOpenDyslexicFont', 'useComicSansFont', 'useCourierNewFont', 'useGeorgiaFont', 'useImpactFont', - 'useLucidaFont', 'useLucidaSansFont', 'usePalatinoFont', 'useTahomaFont', 'useTimesNewRomanFont', - 'useTrebuchetFont', 'useVerdanaFont', 'useSymbolFont', 'useWebdingsFont', 'useWingDingsFont', 'useSansSerifFont', - 'useSerifFont']; + + var fonts = ['useMonospaceFont', 'useMontserratFont', 'useOpenDyslexicFont', 'useComicSansFont', 'useCourierNewFont', + 'useGeorgiaFont', 'useImpactFont', 'useLucidaFont', 'useLucidaSansFont', 'usePalatinoFont', 'useRobotoMonoFont', + 'useTahomaFont', 'useTimesNewRomanFont', 'useTrebuchetFont', 'useVerdanaFont', 'useSymbolFont', 'useWebdingsFont', + 'useWingDingsFont', 'useSansSerifFont', 'useSerifFont']; + $.each(fonts, function(i, font){ if(padcookie.getPref(font) == true){ @@ -731,20 +739,20 @@ var pad = { pad.diagnosticInfo.disconnectedMessage = message; pad.diagnosticInfo.padId = pad.getPadId(); pad.diagnosticInfo.socket = {}; - - //we filter non objects from the socket object and put them in the diagnosticInfo + + //we filter non objects from the socket object and put them in the diagnosticInfo //this ensures we have no cyclic data - this allows us to stringify the data for(var i in socket.socket) { var value = socket.socket[i]; var type = typeof value; - + if(type == "string" || type == "number") { pad.diagnosticInfo.socket[i] = value; } } - + pad.asyncSendDiagnosticInfo(); if (typeof window.ajlog == "string") { diff --git a/src/static/js/pad_automatic_reconnect.js b/src/static/js/pad_automatic_reconnect.js new file mode 100644 index 00000000..b5b99bcd --- /dev/null +++ b/src/static/js/pad_automatic_reconnect.js @@ -0,0 +1,182 @@ + +exports.showCountDownTimerToReconnectOnModal = function($modal, pad) { + if (clientVars.automaticReconnectionTimeout && $modal.is('.with_reconnect_timer')) { + createCountDownElementsIfNecessary($modal); + + var timer = createTimerForModal($modal, pad); + + $modal.find('#cancelreconnect').one('click', function() { + timer.cancel(); + disableAutomaticReconnection($modal); + }); + + enableAutomaticReconnection($modal); + } +} + +var createCountDownElementsIfNecessary = function($modal) { + var elementsDoNotExist = $modal.find('#cancelreconnect').length === 0; + if (elementsDoNotExist) { + var $defaultMessage = $modal.find('#defaulttext'); + var $reconnectButton = $modal.find('#forcereconnect'); + + // create extra DOM elements, if they don't exist + var $reconnectTimerMessage = $('<p class="reconnecttimer"> \ + <span data-l10n-id="pad.modals.reconnecttimer">Trying to reconnect in </span> \ + <span class="timetoexpire"></span> \ + </p>'); + var $cancelReconnect = $('<button id="cancelreconnect" data-l10n-id="pad.modals.cancel">Cancel</button>'); + + localize($reconnectTimerMessage); + localize($cancelReconnect); + + $reconnectTimerMessage.insertAfter($defaultMessage); + $cancelReconnect.insertAfter($reconnectButton); + } +} + +var localize = function($element) { + html10n.translateElement(html10n.translations, $element.get(0)); +}; + +var createTimerForModal = function($modal, pad) { + var timeUntilReconnection = clientVars.automaticReconnectionTimeout * reconnectionTries.nextTry(); + var timer = new CountDownTimer(timeUntilReconnection); + + timer.onTick(function(minutes, seconds) { + updateCountDownTimerMessage($modal, minutes, seconds); + }).onExpire(function() { + var wasANetworkError = $modal.is('.disconnected'); + if (wasANetworkError) { + // cannot simply reconnect, client is having issues to establish connection to server + waitUntilClientCanConnectToServerAndThen(function() { forceReconnection($modal); }, pad); + } else { + forceReconnection($modal); + } + }).start(); + + return timer; +} + +var disableAutomaticReconnection = function($modal) { + toggleAutomaticReconnectionOption($modal, true); +} +var enableAutomaticReconnection = function($modal) { + toggleAutomaticReconnectionOption($modal, false); +} +var toggleAutomaticReconnectionOption = function($modal, disableAutomaticReconnect) { + $modal.find('#cancelreconnect, .reconnecttimer').toggleClass('hidden', disableAutomaticReconnect); + $modal.find('#defaulttext').toggleClass('hidden', !disableAutomaticReconnect); +} + +var waitUntilClientCanConnectToServerAndThen = function(callback, pad) { + whenConnectionIsRestablishedWithServer(callback, pad); + pad.socket.connect(); +} + +var whenConnectionIsRestablishedWithServer = function(callback, pad) { + // only add listener for the first try, don't need to add another listener + // on every unsuccessful try + if (reconnectionTries.counter === 1) { + pad.socket.once('connect', callback); + } +} + +var forceReconnection = function($modal) { + $modal.find('#forcereconnect').click(); +} + +var updateCountDownTimerMessage = function($modal, minutes, seconds) { + minutes = minutes < 10 ? '0' + minutes : minutes; + seconds = seconds < 10 ? '0' + seconds : seconds; + + $modal.find('.timetoexpire').text(minutes + ':' + seconds); +} + +// store number of tries to reconnect to server, in order to increase time to wait +// until next try +var reconnectionTries = { + counter: 0, + + nextTry: function() { + // double the time to try to reconnect on every time reconnection fails + var nextCounterFactor = Math.pow(2, this.counter); + this.counter++; + + return nextCounterFactor; + } +} + +// Timer based on http://stackoverflow.com/a/20618517. +// duration: how many **seconds** until the timer ends +// granularity (optional): how many **milliseconds** between each 'tick' of timer. Default: 1000ms (1s) +var CountDownTimer = function(duration, granularity) { + this.duration = duration; + this.granularity = granularity || 1000; + this.running = false; + + this.onTickCallbacks = []; + this.onExpireCallbacks = []; +} + +CountDownTimer.prototype.start = function() { + if (this.running) { + return; + } + this.running = true; + var start = Date.now(), + that = this, + diff; + + (function timer() { + diff = that.duration - Math.floor((Date.now() - start) / 1000); + + if (diff > 0) { + that.timeoutId = setTimeout(timer, that.granularity); + that.tick(diff); + } else { + that.running = false; + that.tick(0); + that.expire(); + } + }()); +}; + +CountDownTimer.prototype.tick = function(diff) { + var obj = CountDownTimer.parse(diff); + this.onTickCallbacks.forEach(function(callback) { + callback.call(this, obj.minutes, obj.seconds); + }, this); +} +CountDownTimer.prototype.expire = function() { + this.onExpireCallbacks.forEach(function(callback) { + callback.call(this); + }, this); +} + +CountDownTimer.prototype.onTick = function(callback) { + if (typeof callback === 'function') { + this.onTickCallbacks.push(callback); + } + return this; +}; + +CountDownTimer.prototype.onExpire = function(callback) { + if (typeof callback === 'function') { + this.onExpireCallbacks.push(callback); + } + return this; +}; + +CountDownTimer.prototype.cancel = function() { + this.running = false; + clearTimeout(this.timeoutId); + return this; +}; + +CountDownTimer.parse = function(seconds) { + return { + 'minutes': (seconds / 60) | 0, + 'seconds': (seconds % 60) | 0 + }; +}; diff --git a/src/static/js/pad_cookie.js b/src/static/js/pad_cookie.js index b563a7e6..62c88cff 100644 --- a/src/static/js/pad_cookie.js +++ b/src/static/js/pad_cookie.js @@ -23,6 +23,8 @@ var padcookie = (function() { + var cookieName = isHttpsScheme() ? "prefs" : "prefsHttp"; + function getRawCookie() { // returns null if can't get cookie text @@ -31,7 +33,7 @@ var padcookie = (function() return null; } // look for (start of string OR semicolon) followed by whitespace followed by prefs=(something); - var regexResult = document.cookie.match(/(?:^|;)\s*prefs=([^;]*)(?:;|$)/); + var regexResult = document.cookie.match(new RegExp("(?:^|;)\\s*" + cookieName + "=([^;]*)(?:;|$)")); if ((!regexResult) || (!regexResult[1])) { return null; @@ -44,7 +46,7 @@ var padcookie = (function() var expiresDate = new Date(); expiresDate.setFullYear(3000); var secure = isHttpsScheme() ? ";secure" : ""; - document.cookie = ('prefs=' + safeText + ';expires=' + expiresDate.toGMTString() + secure); + document.cookie = (cookieName + "=" + safeText + ";expires=" + expiresDate.toGMTString() + secure); } function parseCookie(text) @@ -122,6 +124,9 @@ var padcookie = (function() { return wasNoCookie; }, + isCookiesEnabled: function() { + return !!getRawCookie(); + }, getPref: function(prefName) { return cookieData[prefName]; diff --git a/src/static/js/pad_editbar.js b/src/static/js/pad_editbar.js index dd1c377a..9cf357aa 100644 --- a/src/static/js/pad_editbar.js +++ b/src/static/js/pad_editbar.js @@ -259,18 +259,25 @@ var padeditbar = (function() // hide all modules and remove highlighting of all buttons if(moduleName == "none") { - var returned = false + var returned = false; for(var i=0;i<self.dropdowns.length;i++) { + var thisModuleName = self.dropdowns[i]; + //skip the userlist - if(self.dropdowns[i] == "users") + if(thisModuleName == "users") continue; - var module = $("#" + self.dropdowns[i]); + var module = $("#" + thisModuleName); + + //skip any "force reconnect" message + var isAForceReconnectMessage = module.find('button#forcereconnect:visible').length > 0; + if(isAForceReconnectMessage) + continue; if(module.css('display') != "none") { - $("li[data-key=" + self.dropdowns[i] + "] > a").removeClass("selected"); + $("li[data-key=" + thisModuleName + "] > a").removeClass("selected"); module.slideUp("fast", cb); returned = true; } @@ -283,16 +290,17 @@ var padeditbar = (function() // respectively add highlighting to the corresponding button for(var i=0;i<self.dropdowns.length;i++) { - var module = $("#" + self.dropdowns[i]); + var thisModuleName = self.dropdowns[i]; + var module = $("#" + thisModuleName); if(module.css('display') != "none") { - $("li[data-key=" + self.dropdowns[i] + "] > a").removeClass("selected"); + $("li[data-key=" + thisModuleName + "] > a").removeClass("selected"); module.slideUp("fast"); } - else if(self.dropdowns[i]==moduleName) + else if(thisModuleName==moduleName) { - $("li[data-key=" + self.dropdowns[i] + "] > a").addClass("selected"); + $("li[data-key=" + thisModuleName + "] > a").addClass("selected"); module.slideDown("fast", cb); } } diff --git a/src/static/js/pad_editor.js b/src/static/js/pad_editor.js index 3e6b49d3..0b282659 100644 --- a/src/static/js/pad_editor.js +++ b/src/static/js/pad_editor.js @@ -1,5 +1,5 @@ /** - * This code is mostly from the old Etherpad. Please help us to comment this code. + * This code is mostly from the old Etherpad. Please help us to comment this code. * This helps other people to understand this code better and helps them to improve it. * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED */ @@ -30,10 +30,12 @@ var padeditor = (function() var settings = undefined; // Array of available fonts - var fonts = ['useMonospaceFont', 'useOpenDyslexicFont', 'useComicSansFont', 'useCourierNewFont', 'useGeorgiaFont', 'useImpactFont', - 'useLucidaFont', 'useLucidaSansFont', 'usePalatinoFont', 'useTahomaFont', 'useTimesNewRomanFont', - 'useTrebuchetFont', 'useVerdanaFont', 'useSymbolFont', 'useWebdingsFont', 'useWingDingsFont', 'useSansSerifFont', - 'useSerifFont']; + + var fonts = ['useMonospaceFont', 'useMontserratFont', 'useOpenDyslexicFont', 'useComicSansFont', 'useCourierNewFont', + 'useGeorgiaFont', 'useImpactFont', 'useLucidaFont', 'useLucidaSansFont', 'usePalatinoFont', 'useRobotoMonoFont', + 'useTahomaFont', 'useTimesNewRomanFont', 'useTrebuchetFont', 'useVerdanaFont', 'useSymbolFont', 'useWebdingsFont', + 'useWingDingsFont', 'useSansSerifFont', 'useSerifFont']; + var self = { ace: null, @@ -102,7 +104,7 @@ var padeditor = (function() pad.changeViewOption(font, $("#viewfontmenu").val() == sfont); }); }); - + // Language html10n.bind('localized', function() { $("#languagemenu").val(html10n.getLanguage()); @@ -161,6 +163,7 @@ var padeditor = (function() font = font.replace("Font",""); font = font.toLowerCase(); if(font === "monospace") self.ace.setProperty("textface", "monospace"); + if(font === "montserrat") self.ace.setProperty("textface", "Montserrat"); if(font === "opendyslexic") self.ace.setProperty("textface", "OpenDyslexic"); if(font === "comicsans") self.ace.setProperty("textface", "'Comic Sans MS','Comic Sans',cursive"); if(font === "georgia") self.ace.setProperty("textface", "Georgia,'Bitstream Charter',serif"); @@ -168,6 +171,7 @@ var padeditor = (function() if(font === "lucida") self.ace.setProperty("textface", "Lucida,'Lucida Serif','Lucida Bright',serif"); if(font === "lucidasans") self.ace.setProperty("textface", "'Lucida Sans','Lucida Grande','Lucida Sans Unicode','Luxi Sans',sans-serif"); if(font === "palatino") self.ace.setProperty("textface", "Palatino,'Palatino Linotype','URW Palladio L',Georgia,serif"); + if(font === "robotomono") self.ace.setProperty("textface", "RobotoMono"); if(font === "tahoma") self.ace.setProperty("textface", "Tahoma,sans-serif"); if(font === "timesnewroman") self.ace.setProperty("textface", "'Times New Roman',Times,serif"); if(font === "trebuchet") self.ace.setProperty("textface", "'Trebuchet MS',sans-serif"); diff --git a/src/static/js/pad_modals.js b/src/static/js/pad_modals.js index 67b03662..2fc621dc 100644 --- a/src/static/js/pad_modals.js +++ b/src/static/js/pad_modals.js @@ -1,5 +1,5 @@ /** - * This code is mostly from the old Etherpad. Please help us to comment this code. + * This code is mostly from the old Etherpad. Please help us to comment this code. * This helps other people to understand this code better and helps them to improve it. * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED */ @@ -19,8 +19,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + var padeditbar = require('./pad_editbar').padeditbar; +var automaticReconnect = require('./pad_automatic_reconnect'); var padmodals = (function() { @@ -35,6 +36,10 @@ var padmodals = (function() padeditbar.toggleDropDown("none", function() { $("#connectivity .visible").removeClass('visible'); $("#connectivity ."+messageId).addClass('visible'); + + var $modal = $('#connectivity .' + messageId); + automaticReconnect.showCountDownTimerToReconnectOnModal($modal, pad); + padeditbar.toggleDropDown("connectivity"); }); }, diff --git a/src/templates/index.html b/src/templates/index.html index e1f59c1e..92bea582 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -161,7 +161,7 @@ <div id="wrapper"> <% e.begin_block("indexWrapper"); %> <div id="inner"> - <buttOn id="button" onclick="go2Random()" data-l10n-id="index.newPad"></button> + <button id="button" onclick="go2Random()" data-l10n-id="index.newPad"></button> <label id="label" for="padname" data-l10n-id="index.createOpenPad"></label> <form action="#" onsubmit="go2Name();return false;"> <input type="text" id="padname" maxlength="50" autofocus x-webkit-speech> diff --git a/src/templates/pad.html b/src/templates/pad.html index 3d89f9d0..9a9c6f07 100644 --- a/src/templates/pad.html +++ b/src/templates/pad.html @@ -161,6 +161,7 @@ <select id="viewfontmenu"> <option value="normal" data-l10n-id="pad.settings.fontType.normal"></option> <option value="monospace" data-l10n-id="pad.settings.fontType.monospaced"></option> + <option value="montserrat" data-l10n-id="pad.settings.fontType.montserrat"></option> <option value="opendyslexic" data-l10n-id="pad.settings.fontType.opendyslexic"></option> <option value="comicsans" data-l10n-id="pad.settings.fontType.comicsans"></option> <option value="georgia" data-l10n-id="pad.settings.fontType.georgia"></option> @@ -168,6 +169,7 @@ <option value="lucida" data-l10n-id="pad.settings.fontType.lucida"></option> <option value="lucidasans" data-l10n-id="pad.settings.fontType.lucidasans"></option> <option value="palatino" data-l10n-id="pad.settings.fontType.palatino"></option> + <option value="robotomono" data-l10n-id="pad.settings.fontType.robotomono"></option> <option value="tahoma" data-l10n-id="pad.settings.fontType.tahoma"></option> <option value="timesnewroman" data-l10n-id="pad.settings.fontType.timesnewroman"></option> <option value="trebuchet" data-l10n-id="pad.settings.fontType.trebuchet"></option> @@ -249,12 +251,12 @@ <div class="userdup"> <h1 data-l10n-id="pad.modals.userdup"></h1> <h2 data-l10n-id="pad.modals.userdup.explanation"></h2> - <p data-l10n-id="pad.modals.userdup.advice"></p> + <p id="defaulttext" data-l10n-id="pad.modals.userdup.advice"></p> <button id="forcereconnect" data-l10n-id="pad.modals.forcereconnect"></button> </div> <div class="unauth"> <h1 data-l10n-id="pad.modals.unauth"></h1> - <p data-l10n-id="pad.modals.unauth.explanation"></p> + <p id="defaulttext" data-l10n-id="pad.modals.unauth.explanation"></p> <button id="forcereconnect" data-l10n-id="pad.modals.forcereconnect"></button> </div> <div class="looping"> @@ -267,16 +269,16 @@ <h2 data-l10n-id="pad.modals.initsocketfail.explanation"></h2> <p data-l10n-id="pad.modals.initsocketfail.cause"></p> </div> - <div class="slowcommit"> + <div class="slowcommit with_reconnect_timer"> <h1 data-l10n-id="pad.modals.disconnected"></h1> <h2 data-l10n-id="pad.modals.slowcommit.explanation"></h2> - <p data-l10n-id="pad.modals.slowcommit.cause"></p> + <p id="defaulttext" data-l10n-id="pad.modals.slowcommit.cause"></p> <button id="forcereconnect" data-l10n-id="pad.modals.forcereconnect"></button> </div> - <div class="badChangeset"> + <div class="badChangeset with_reconnect_timer"> <h1 data-l10n-id="pad.modals.disconnected"></h1> <h2 data-l10n-id="pad.modals.badChangeset.explanation"></h2> - <p data-l10n-id="pad.modals.badChangeset.cause"></p> + <p id="defaulttext" data-l10n-id="pad.modals.badChangeset.cause"></p> <button id="forcereconnect" data-l10n-id="pad.modals.forcereconnect"></button> </div> <div class="corruptPad"> @@ -288,11 +290,11 @@ <h1 data-l10n-id="pad.modals.deleted"></h1> <p data-l10n-id="pad.modals.deleted.explanation"></p> </div> - <div class="disconnected"> + <div class="disconnected with_reconnect_timer"> <% e.begin_block("disconnected"); %> <h1 data-l10n-id="pad.modals.disconnected"></h1> <h2 data-l10n-id="pad.modals.disconnected.explanation"></h2> - <p data-l10n-id="pad.modals.disconnected.cause"></p> + <p id="defaulttext" data-l10n-id="pad.modals.disconnected.cause"></p> <button id="forcereconnect" data-l10n-id="pad.modals.forcereconnect"></button> <% e.end_block(); %> </div> diff --git a/tests/frontend/specs/automatic_reconnect.js b/tests/frontend/specs/automatic_reconnect.js new file mode 100644 index 00000000..e2d2df36 --- /dev/null +++ b/tests/frontend/specs/automatic_reconnect.js @@ -0,0 +1,71 @@ +describe('Automatic pad reload on Force Reconnect message', function() { + var padId, $originalPadFrame; + + beforeEach(function(done) { + padId = helper.newPad(function() { + // enable userdup error to have timer to force reconnect + var $errorMessageModal = helper.padChrome$('#connectivity .userdup'); + $errorMessageModal.addClass('with_reconnect_timer'); + + // make sure there's a timeout set, otherwise automatic reconnect won't be enabled + helper.padChrome$.window.clientVars.automaticReconnectionTimeout = 2; + + // open same pad on another iframe, to force userdup error + var $otherIframeWithSamePad = $('<iframe src="/p/' + padId + '" style="height: 1px;"></iframe>'); + $originalPadFrame = $('#iframe-container iframe'); + $otherIframeWithSamePad.insertAfter($originalPadFrame); + + // wait for modal to be displayed + helper.waitFor(function() { + return $errorMessageModal.is(':visible'); + }, 50000).done(done); + }); + + this.timeout(60000); + }); + + it('displays a count down timer to automatically reconnect', function(done) { + var $errorMessageModal = helper.padChrome$('#connectivity .userdup'); + var $countDownTimer = $errorMessageModal.find('.reconnecttimer'); + + expect($countDownTimer.is(':visible')).to.be(true); + + done(); + }); + + context('and user clicks on Cancel', function() { + beforeEach(function() { + var $errorMessageModal = helper.padChrome$('#connectivity .userdup'); + $errorMessageModal.find('#cancelreconnect').click(); + }); + + it('does not show Cancel button nor timer anymore', function(done) { + var $errorMessageModal = helper.padChrome$('#connectivity .userdup'); + var $countDownTimer = $errorMessageModal.find('.reconnecttimer'); + var $cancelButton = $errorMessageModal.find('#cancelreconnect'); + + expect($countDownTimer.is(':visible')).to.be(false); + expect($cancelButton.is(':visible')).to.be(false); + + done(); + }); + }); + + context('and user does not click on Cancel until timer expires', function() { + var padWasReloaded = false; + + beforeEach(function() { + $originalPadFrame.one('load', function() { + padWasReloaded = true; + }); + }); + + it('reloads the pad', function(done) { + helper.waitFor(function() { + return padWasReloaded; + }, 5000).done(done); + + this.timeout(5000); + }); + }); +}); diff --git a/tests/frontend/specs/drag_and_drop.js b/tests/frontend/specs/drag_and_drop.js index bcec0bd2..821d3aac 100644 --- a/tests/frontend/specs/drag_and_drop.js +++ b/tests/frontend/specs/drag_and_drop.js @@ -154,7 +154,15 @@ describe('drag and drop', function() { var $target = getLine(targetLineNumber); $target.sendkeys('{selectall}{rightarrow}{leftarrow}'); - // insert content - innerDocument.execCommand('insertHTML', false, draggedHtml); + // Insert content. + // Based on http://stackoverflow.com/a/6691294, to be IE-compatible + var range = innerDocument.getSelection().getRangeAt(0); + var frag = innerDocument.createDocumentFragment(); + var el = innerDocument.createElement('div'); + el.innerHTML = draggedHtml; + while (el.firstChild) { + frag.appendChild(el.firstChild); + } + range.insertNode(frag); } }); diff --git a/tests/frontend/specs/helper.js b/tests/frontend/specs/helper.js index bb47f4dc..8520769a 100644 --- a/tests/frontend/specs/helper.js +++ b/tests/frontend/specs/helper.js @@ -101,20 +101,21 @@ describe("the test helper", function(){ // function to support tests, use a single way to represent whitespaces var cleanText = function(text){ return text - .replace(/\n/gi, "\\\\n") // avoid \n to be replaced by \s on next line - .replace(/\s/gi, " ") - .replace(/\\\\n/gi, "\n"); // move back \n to its original state + // IE replaces line breaks with a whitespace, so we need to unify its behavior + // for other browsers, to have all tests running for all browsers + .replace(/\n/gi, "") + .replace(/\s/gi, " "); } before(function(done){ helper.newPad(function() { // create some lines to be used on the tests var $firstLine = helper.padInner$("div").first(); - $firstLine.sendkeys("{selectall}some{enter}short{enter}lines{enter}to test{enter}"); + $firstLine.sendkeys("{selectall}some{enter}short{enter}lines{enter}to test{enter}{enter}"); // wait for lines to be split helper.waitFor(function(){ - var $fourthLine = helper.padInner$("div").slice(3,4); + var $fourthLine = helper.padInner$("div").eq(3); return $fourthLine.text() === "to test"; }).done(done); }); @@ -129,13 +130,13 @@ describe("the test helper", function(){ var endOffset = 4; var $lines = inner$("div"); - var $startLine = $lines.slice(1,2); - var $endLine = $lines.slice(3,4); + var $startLine = $lines.eq(1); + var $endLine = $lines.eq(3); helper.selectLines($startLine, $endLine, startOffset, endOffset); var selection = inner$.document.getSelection(); - expect(cleanText(selection.toString())).to.be("ort \nlines \nto t"); + expect(cleanText(selection.toString())).to.be("ort lines to t"); done(); }); @@ -147,13 +148,13 @@ describe("the test helper", function(){ var endOffset = 1; var $lines = inner$("div"); - var $startLine = $lines.slice(1,2); - var $endLine = $lines.slice(4,5); + var $startLine = $lines.eq(1); + var $endLine = $lines.eq(4); helper.selectLines($startLine, $endLine, startOffset, endOffset); var selection = inner$.document.getSelection(); - expect(cleanText(selection.toString())).to.be("ort \nlines \nto test\n"); + expect(cleanText(selection.toString())).to.be("ort lines to test"); done(); }); @@ -165,13 +166,13 @@ describe("the test helper", function(){ var endOffset = 0; var $lines = inner$("div"); - var $startLine = $lines.slice(1,2); - var $endLine = $lines.slice(3,4); + var $startLine = $lines.eq(1); + var $endLine = $lines.eq(3); helper.selectLines($startLine, $endLine, startOffset, endOffset); var selection = inner$.document.getSelection(); - expect(cleanText(selection.toString())).to.be("ort \nlines \n"); + expect(cleanText(selection.toString())).to.be("ort lines "); done(); }); @@ -183,13 +184,13 @@ describe("the test helper", function(){ var endOffset = 50; var $lines = inner$("div"); - var $startLine = $lines.slice(1,2); - var $endLine = $lines.slice(3,4); + var $startLine = $lines.eq(1); + var $endLine = $lines.eq(3); helper.selectLines($startLine, $endLine, startOffset, endOffset); var selection = inner$.document.getSelection(); - expect(cleanText(selection.toString())).to.be("ort \nlines \nto test"); + expect(cleanText(selection.toString())).to.be("ort lines to test"); done(); }); @@ -198,13 +199,13 @@ describe("the test helper", function(){ var inner$ = helper.padInner$; var $lines = inner$("div"); - var $startLine = $lines.slice(1,2); - var $endLine = $lines.slice(3,4); + var $startLine = $lines.eq(1); + var $endLine = $lines.eq(3); helper.selectLines($startLine, $endLine); var selection = inner$.document.getSelection(); - expect(cleanText(selection.toString())).to.be("short \nlines \nto test"); + expect(cleanText(selection.toString())).to.be("short lines to test"); done(); }); diff --git a/tests/frontend/specs/ordered_list.js b/tests/frontend/specs/ordered_list.js index ca7d755e..57196fef 100644 --- a/tests/frontend/specs/ordered_list.js +++ b/tests/frontend/specs/ordered_list.js @@ -5,8 +5,8 @@ describe("assign ordered list", function(){ this.timeout(60000); }); - it("insert ordered list text", function(done){ - var inner$ = helper.padInner$; + it("inserts ordered list text", function(done){ + var inner$ = helper.padInner$; var chrome$ = helper.padChrome$; var $insertorderedlistButton = chrome$(".buttonicon-insertorderedlist"); @@ -17,8 +17,72 @@ describe("assign ordered list", function(){ }).done(done); }); + context('when user presses Ctrl+Shift+N', function() { + context('and pad shortcut is enabled', function() { + beforeEach(function() { + makeSureShortcutIsEnabled('cmdShiftN'); + triggerCtrlShiftShortcut('N'); + }); + + it('inserts unordered list', function(done) { + helper.waitFor(function() { + return helper.padInner$('div').first().find('ol li').length === 1; + }).done(done); + }); + }); + + context('and pad shortcut is disabled', function() { + beforeEach(function() { + makeSureShortcutIsDisabled('cmdShiftN'); + triggerCtrlShiftShortcut('N'); + }); + + it('does not insert unordered list', function(done) { + helper.waitFor(function() { + return helper.padInner$('div').first().find('ol li').length === 1; + }).done(function() { + expect().fail(function() { return 'Unordered list inserted, should ignore shortcut' }); + }).fail(function() { + done(); + }); + }); + }); + }); + + context('when user presses Ctrl+Shift+1', function() { + context('and pad shortcut is enabled', function() { + beforeEach(function() { + makeSureShortcutIsEnabled('cmdShift1'); + triggerCtrlShiftShortcut('1'); + }); + + it('inserts unordered list', function(done) { + helper.waitFor(function() { + return helper.padInner$('div').first().find('ol li').length === 1; + }).done(done); + }); + }); + + context('and pad shortcut is disabled', function() { + beforeEach(function() { + makeSureShortcutIsDisabled('cmdShift1'); + triggerCtrlShiftShortcut('1'); + }); + + it('does not insert unordered list', function(done) { + helper.waitFor(function() { + return helper.padInner$('div').first().find('ol li').length === 1; + }).done(function() { + expect().fail(function() { return 'Unordered list inserted, should ignore shortcut' }); + }).fail(function() { + done(); + }); + }); + }); + }); + xit("issue #1125 keeps the numbered list on enter for the new line - EMULATES PASTING INTO A PAD", function(done){ - var inner$ = helper.padInner$; + var inner$ = helper.padInner$; var chrome$ = helper.padChrome$; var $insertorderedlistButton = chrome$(".buttonicon-insertorderedlist"); @@ -26,9 +90,9 @@ describe("assign ordered list", function(){ //type a bit, make a line break and type again var $firstTextElement = inner$("div span").first(); - $firstTextElement.sendkeys('line 1'); - $firstTextElement.sendkeys('{enter}'); - $firstTextElement.sendkeys('line 2'); + $firstTextElement.sendkeys('line 1'); + $firstTextElement.sendkeys('{enter}'); + $firstTextElement.sendkeys('line 2'); $firstTextElement.sendkeys('{enter}'); helper.waitFor(function(){ @@ -44,4 +108,26 @@ describe("assign ordered list", function(){ done(); }); }); + + var triggerCtrlShiftShortcut = function(shortcutChar) { + var inner$ = helper.padInner$; + if(inner$(window)[0].bowser.firefox || inner$(window)[0].bowser.modernIE) { // if it's a mozilla or IE + var evtType = "keypress"; + }else{ + var evtType = "keydown"; + } + var e = inner$.Event(evtType); + e.ctrlKey = true; + e.shiftKey = true; + e.which = shortcutChar.toString().charCodeAt(0); + inner$("#innerdocbody").trigger(e); + } + + var makeSureShortcutIsDisabled = function(shortcut) { + helper.padChrome$.window.clientVars.padShortcutEnabled[shortcut] = false; + } + var makeSureShortcutIsEnabled = function(shortcut) { + helper.padChrome$.window.clientVars.padShortcutEnabled[shortcut] = true; + } + }); diff --git a/tests/frontend/specs/pad_modal.js b/tests/frontend/specs/pad_modal.js new file mode 100644 index 00000000..80752e4b --- /dev/null +++ b/tests/frontend/specs/pad_modal.js @@ -0,0 +1,131 @@ +describe('Pad modal', function() { + context('when modal is a "force reconnect" message', function() { + var MODAL_SELECTOR = '#connectivity .slowcommit'; + + beforeEach(function(done) { + helper.newPad(function() { + // force a "slowcommit" error + helper.padChrome$.window.pad.handleChannelStateChange('DISCONNECTED', 'slowcommit'); + + // wait for modal to be displayed + var $modal = helper.padChrome$(MODAL_SELECTOR); + helper.waitFor(function() { + return $modal.is(':visible'); + }, 50000).done(done); + }); + + this.timeout(60000); + }); + + it('disables editor', function(done) { + expect(isEditorDisabled()).to.be(true); + + done(); + }); + + context('and user clicks on editor', function() { + beforeEach(function() { + clickOnPadInner(); + }); + + it('does not close the modal', function(done) { + var $modal = helper.padChrome$(MODAL_SELECTOR); + var modalIsVisible = $modal.is(':visible'); + + expect(modalIsVisible).to.be(true); + + done(); + }); + }); + + context('and user clicks on pad outer', function() { + beforeEach(function() { + clickOnPadOuter(); + }); + + it('does not close the modal', function(done) { + var $modal = helper.padChrome$(MODAL_SELECTOR); + var modalIsVisible = $modal.is(':visible'); + + expect(modalIsVisible).to.be(true); + + done(); + }); + }); + }); + + // we use "settings" here, but other modals have the same behaviour + context('when modal is not an error message', function() { + var MODAL_SELECTOR = '#settings'; + + beforeEach(function(done) { + helper.newPad(function() { + openSettingsAndWaitForModalToBeVisible(done); + }); + + this.timeout(60000); + }); + + it('does not disable editor', function(done) { + expect(isEditorDisabled()).to.be(false); + done(); + }); + + context('and user clicks on editor', function() { + beforeEach(function() { + clickOnPadInner(); + }); + + it('closes the modal', function(done) { + expect(isModalOpened(MODAL_SELECTOR)).to.be(false); + done(); + }); + }); + + context('and user clicks on pad outer', function() { + beforeEach(function() { + clickOnPadOuter(); + }); + + it('closes the modal', function(done) { + expect(isModalOpened(MODAL_SELECTOR)).to.be(false); + done(); + }); + }); + }); + + var clickOnPadInner = function() { + var $editor = helper.padInner$('#innerdocbody'); + $editor.click(); + } + + var clickOnPadOuter = function() { + var $lineNumbersColumn = helper.padOuter$('#sidedivinner'); + $lineNumbersColumn.click(); + } + + var openSettingsAndWaitForModalToBeVisible = function(done) { + helper.padChrome$('.buttonicon-settings').click(); + + // wait for modal to be displayed + var modalSelector = '#settings'; + helper.waitFor(function() { + return isModalOpened(modalSelector); + }, 10000).done(done); + } + + var isEditorDisabled = function() { + var editorDocument = helper.padOuter$("iframe[name='ace_inner']").get(0).contentDocument; + var editorBody = editorDocument.getElementById('innerdocbody'); + + var editorIsDisabled = editorBody.contentEditable === 'false' // IE/Safari + || editorDocument.designMode === 'off'; // other browsers + + return editorIsDisabled; + } + + var isModalOpened = function(modalSelector) { + var $modal = helper.padChrome$(modalSelector); + return $modal.is(':visible'); + } +}); diff --git a/tests/frontend/travis/sauce_tunnel.sh b/tests/frontend/travis/sauce_tunnel.sh index f519f8d9..b19268d0 100755 --- a/tests/frontend/travis/sauce_tunnel.sh +++ b/tests/frontend/travis/sauce_tunnel.sh @@ -1,16 +1,14 @@ #!/bin/bash # download and unzip the sauce connector -curl http://saucelabs.com/downloads/Sauce-Connect-latest.zip > /tmp/sauce.zip -unzip /tmp/sauce.zip -d /tmp +curl https://saucelabs.com/downloads/sc-latest-linux.tar.gz > /tmp/sauce.tar.gz +tar zxf /tmp/sauce.tar.gz --directory /tmp +mv /tmp/sc-*-linux /tmp/sauce_connect # start the sauce connector in background and make sure it doesn't output the secret key -(java -jar /tmp/Sauce-Connect.jar $SAUCE_USERNAME $SAUCE_ACCESS_KEY -f /tmp/tunnel > /dev/null )& - -# save the sauce pid in a file -echo $! > /tmp/sauce.pid +(/tmp/sauce_connect/bin/sc --user $SAUCE_USERNAME --key $SAUCE_ACCESS_KEY --pidfile /tmp/sauce.pid --readyfile /tmp/tunnel > /dev/null )& # wait for the tunnel to build up while [ ! -e "/tmp/tunnel" ] do - sleep 1 -done
\ No newline at end of file + sleep 1 +done |