Merge branch 'release/1.8.5'

This commit is contained in:
Stefan Mueller 2020-09-08 22:34:02 +02:00
commit f3d950c664
208 changed files with 25420 additions and 9270 deletions

View file

@ -1,4 +1,7 @@
*~
.dockerignore
.hg .hg
Dockerfile
# Remove the git objects, logs, etc. to make final image smaller. # Remove the git objects, logs, etc. to make final image smaller.
# Some files still need to be in the .git directory, because Etherpad at # Some files still need to be in the .git directory, because Etherpad at

View file

@ -1,12 +1,11 @@
* * * ---
name: Bug report name: Bug report
about: Create a report to help us improve about: Create a report to help us improve
title: '' title: ''
labels: bug labels: ''
assignees: assignees: ''
* * * ---
**Describe the bug** **Describe the bug**
A clear and concise description of what the bug is. A clear and concise description of what the bug is.
@ -24,23 +23,16 @@ A clear and concise description of what you expected to happen.
**Screenshots** **Screenshots**
If applicable, add screenshots to help explain your problem. If applicable, add screenshots to help explain your problem.
**Environment (please complete the following information):**
- Etherpad Version: (e.g. 1.8.0)
- Deployment (manual install, docker, ...)
**Desktop (please complete the following information):** **Desktop (please complete the following information):**
- OS: [e.g. iOS]
- OS: (e.g. iOS) - Browser [e.g. chrome, safari]
- Browser (e.g. chrome, safari) - Version [e.g. 22]
- Version (e.g. 22)
**Smartphone (please complete the following information):** **Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- Device: (e.g. iPhone6) - OS: [e.g. iOS8.1]
- OS: (e.g. iOS8.1) - Browser [e.g. stock browser, safari]
- Browser (e.g. stock browser, safari) - Version [e.g. 22]
- Version (e.g. 22)
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.

View file

@ -1,3 +1,12 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: Feature Request
assignees: ''
---
* * * * * *
name: Feature request name: Feature request
@ -19,3 +28,6 @@ A clear and concise description of any alternative solutions or features you've
**Additional context** **Additional context**
Add any other context or screenshots about the feature request here. Add any other context or screenshots about the feature request here.
**Plugin?**
Might this feature be better suited to being a plugin? Usually features that can be plugins, should be.

View file

@ -0,0 +1,30 @@
---
name: Plugin request template
about: Suggest a plugin for Etherpad
title: ''
labels: Plugin Request
assignees: JohnMcLear
---
* * *
name: Plugin request
about: Suggest a plugin for this project
title: ''
labels: plugin request
assignees:
* * *
**Is your plugin request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when (...)
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the plugin request here.

View file

@ -0,0 +1,10 @@
---
name: Security issue
about: Notify the Etherpad foundation of a Security issue
title: ''
labels: security
assignees: ''
---
Please email contact@etherpad.org with details of the security issue prior to posting here.

13
.github/ISSUE_TEMPLATE/security.md vendored Normal file
View file

@ -0,0 +1,13 @@
* * *
name: Security notification
about: Disclose a security issue in Etherpad
title: ''
labels: security
assignees:
* * *
**Our Security disclosure process**
1. Please email contact@etherpad.org with detials of the exploit including steps to replicate.
1. Once confirmed we will provide a confirmation, patch and CVE details.

23
.github/stale.yml vendored Normal file
View file

@ -0,0 +1,23 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
- Bug
- Serious Bug
- Minor bug
- Black hole bug
- Special case Bug
- Upstream bug
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

54
.github/workflows/codeql-analysis.yml vendored Normal file
View file

@ -0,0 +1,54 @@
name: "CodeQL"
on:
push:
branches: [develop, master]
pull_request:
# The branches below must be a subset of the branches above
branches: [develop]
schedule:
- cron: '0 13 * * 1'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View file

@ -6,13 +6,17 @@ node_js:
services: services:
- docker - docker
cache: false
before_install:
- sudo add-apt-repository -y ppa:libreoffice/ppa
- sudo apt-get update
- sudo apt-get -y install libreoffice
- sudo apt-get -y install libreoffice-pdfimport
install: install:
- "bin/installDeps.sh" - "bin/installDeps.sh"
- "export GIT_HASH=$(git rev-parse --verify --short HEAD)" - "export GIT_HASH=$(git rev-parse --verify --short HEAD)"
- "npm install ep_test_line_attrib"
before_script:
- "tests/frontend/travis/sauce_tunnel.sh"
script: script:
- "tests/frontend/travis/runner.sh" - "tests/frontend/travis/runner.sh"
@ -24,25 +28,39 @@ env:
jobs: jobs:
include: include:
# we can only frontend tests from the ether/ organization and not from forks.
# To request tests to be run ask a maintainer to fork your repo to ether/
- if: fork = false
name: "Test the Frontend"
install:
#FIXME
- "sed 's/\"loglevel\": \"INFO\",/\"loglevel\": \"WARN\",/g' settings.json.template > settings.json"
- "tests/frontend/travis/sauce_tunnel.sh"
- "bin/installDeps.sh"
- "export GIT_HASH=$(git rev-parse --verify --short HEAD)"
script:
- "tests/frontend/travis/runner.sh"
- name: "Run the Backend tests" - name: "Run the Backend tests"
install: install:
- "bin/installDeps.sh"
- "cd src && npm install && cd -" - "cd src && npm install && cd -"
script: script:
- "tests/frontend/travis/runnerBackend.sh" - "tests/frontend/travis/runnerBackend.sh"
- name: "Test the Frontend" ## Temporarily commented out the Dockerfile tests
# - name: "Test the Dockerfile"
# install:
# - "cd src && npm install && cd -"
# script:
# - "docker build -t etherpad:test ."
# - "docker run -d -p 9001:9001 etherpad:test && sleep 3"
# - "cd src && npm run test-container"
- name: "Load test Etherpad"
install: install:
- "bin/installDeps.sh" - "bin/installDeps.sh"
- "export GIT_HASH=$(git rev-parse --verify --short HEAD)"
- "npm install ep_test_line_attrib"
script:
- "tests/frontend/travis/runner.sh"
- name: "Test the Dockerfile"
install:
- "cd src && npm install && cd -" - "cd src && npm install && cd -"
- "npm install -g etherpad-load-test"
script: script:
- "docker build -t etherpad:test ." - "tests/frontend/travis/runnerLoadTest.sh"
- "docker run -d -p 9001:9001 etherpad:test && sleep 3"
- "cd src && npm run test-container"
notifications: notifications:
irc: irc:

View file

@ -1,3 +1,47 @@
# Develop -- TODO Change to 1.8.x.
* ...
# 1.8.5
* IMPORTANT DROP OF SUPPORT: Drop support for IE. Browsers now need async/await.
* IMPORTANT SECURITY: Rate limit Commits when env=production
* SECURITY: Non completed uploads no longer crash Etherpad
* SECURITY: Log authentication requests
* FEATURE: Support ES6 (migrate from Uglify-JS to Terser)
* FEATURE: Improve support for non-cookie enabled browsers
* FEATURE: New hooks for ``index.html``
* FEATURE: New script to delete sessions.
* FEATURE: New setting to allow import withing an author session on a pad
* FEATURE: Checks Etherpad version on startup and notifies if update is available. Also available in ``/admin`` interface.
* FEATURE: Timeslider updates pad location to most recent edit
* MINOR: Outdent UL/LI items on removal of list item
* MINOR: Various UL/LI import/export bugs
* MINOR: PDF export fix
* MINOR: Front end tests no longer run (and subsequently error) on pull requests
* MINOR: Fix issue with </li> closing a list before it opens
* MINOR: Fix bug where large pads would fire a console error in timeslider
* MINOR: Fix ?showChat URL param issue
* MINOR: Issue where timeslider URI fails to be correct if padID is numeric
* MINOR: Include prompt for clear authorship when entire document is selected
* MINOR: Include full document aText every 100 revisions to make pad restoration on database curruption achievable
* MINOR: Several Colibris CSS fixes
* MINOR: Use mime library for mime types instead of hard-coded.
* MINOR: Don't show "new pad button" if instance is read only
* MINOR: Use latest NodeJS when doing Windows build
* MINOR: Change disconnect logic to reconnect instead of silently failing
* MINOR: Update SocketIO, async, jQuery and Mocha which were stuck due to stale code.
* MINOR: Rewrite the majority of the ``bin`` scripts to use more modern syntax
* MINOR: Improved CSS anomation through prefers-reduced-motion
* PERFORMANCE: Use workers (where possible) to minify CSS/JS on first page request. This improves initial startup times.
* PERFORMANCE: Cache EJS files improving page load speed when maxAge > 0.
* PERFORMANCE: Fix performance for large pads
* TESTS: Additional test coverage for OL/LI/Import/Export
* TESTS: Include Simulated Load Testing in CI.
* TESTS: Include content collector tests to test contentcollector.js logic external to pad dependents.
* TESTS: Include fuzzing import test.
* TESTS: Ensure CI is no longer using any cache
* TESTS: Fix various tests...
* TESTS: Various additional Travis testing including libreoffice import/export
# 1.8.4 # 1.8.4
* FIX: fix a performance regression on MySQL introduced in 1.8.3 * FIX: fix a performance regression on MySQL introduced in 1.8.3
* FIX: when running behind a reverse proxy and exposed in an inner directory, fonts and toolbar icons should now be visible. This is a regression introduced in 1.8.3 * FIX: when running behind a reverse proxy and exposed in an inner directory, fonts and toolbar icons should now be visible. This is a regression introduced in 1.8.3

View file

@ -42,7 +42,7 @@ RUN bin/installDeps.sh && \
# #
# Bash trick: in the for loop ${ETHERPAD_PLUGINS} is NOT quoted, in order to be # Bash trick: in the for loop ${ETHERPAD_PLUGINS} is NOT quoted, in order to be
# able to split at spaces. # able to split at spaces.
RUN for PLUGIN_NAME in ${ETHERPAD_PLUGINS}; do npm install "${PLUGIN_NAME}"; done RUN for PLUGIN_NAME in ${ETHERPAD_PLUGINS}; do npm install "${PLUGIN_NAME}" || exit 1; done
# Copy the configuration file. # Copy the configuration file.
COPY --chown=etherpad:0 ./settings.json.docker /opt/etherpad-lite/settings.json COPY --chown=etherpad:0 ./settings.json.docker /opt/etherpad-lite/settings.json

View file

@ -1,6 +1,8 @@
# A real-time collaborative editor for the web # A real-time collaborative editor for the web
<a href="https://hub.docker.com/r/etherpad/etherpad"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/etherpad/etherpad"></a> <a href="https://hub.docker.com/r/etherpad/etherpad"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/etherpad/etherpad"></a>
[![Travis (.org)](https://img.shields.io/travis/ether/etherpad-lite)](https://travis-ci.org/github/ether/etherpad-lite)
[![Travis (.org)](https://api.travis-ci.org/ether/etherpad-lite.svg?branch=develop)](https://travis-ci.org/github/ether/etherpad-lite)
![Demo Etherpad Animated Jif](doc/images/etherpad_demo.gif "Etherpad in action") ![Demo Etherpad Animated Jif](doc/images/etherpad_demo.gif "Etherpad in action")
# About # About
@ -92,6 +94,13 @@ If you prefer, `ep_hash_auth` also gives you the option of storing the users in
Etherpad is very customizable through plugins. Instructions for installing themes and plugins can be found in [the plugin wiki article](https://github.com/ether/etherpad-lite/wiki/Available-Plugins). Etherpad is very customizable through plugins. Instructions for installing themes and plugins can be found in [the plugin wiki article](https://github.com/ether/etherpad-lite/wiki/Available-Plugins).
## Getting the full features
Run the following command in your Etherpad folder to get all of the features visible in the demo gif:
```
npm install ep_headings2 ep_markdown ep_comments_page ep_align ep_page_view ep_font_color ep_webrtc ep_embedded_hyperlinks2
```
## Customize the style with skin variants ## Customize the style with skin variants
Open <http://127.0.0.1:9001/p/test#skinvariantsbuilder> in your browser and start playing ! Open <http://127.0.0.1:9001/p/test#skinvariantsbuilder> in your browser and start playing !
@ -130,10 +139,12 @@ OpenAPI (previously swagger) definitions for the API are exposed under `/api/ope
There is a [jQuery plugin](https://github.com/ether/etherpad-lite-jquery-plugin) that helps you to embed Pads into your website. There is a [jQuery plugin](https://github.com/ether/etherpad-lite-jquery-plugin) that helps you to embed Pads into your website.
# Plugin Framework # Plugin Framework
Etherpad offers a plugin framework, allowing you to easily add your own features. By default your Etherpad is extremely light-weight and it's up to you to customize your experience. Once you have Etherpad installed you should visit the plugin page and take control. Etherpad offers a plugin framework, allowing you to easily add your own features. By default your Etherpad is extremely light-weight and it's up to you to customize your experience. Once you have Etherpad installed you should [visit the plugin page](https://static.etherpad.org/) and take control.
# Translations / Localizations (i18n / l10n) # Translations / Localizations (i18n / l10n)
Etherpad comes with translations into all languages thanks to the team at TranslateWiki. Etherpad comes with translations into all languages thanks to the team at [TranslateWiki](https://translatewiki.net/).
If you require translations in [plugins](https://static.etherpad.org/) please send pull request to each plugin individually.
# FAQ # FAQ
Visit the **[FAQ](https://github.com/ether/etherpad-lite/wiki/FAQ)**. Visit the **[FAQ](https://github.com/ether/etherpad-lite/wiki/FAQ)**.

5
SECURITY.md Normal file
View file

@ -0,0 +1,5 @@
# Security Policy
## Reporting a Vulnerability
Please email contact@etherpad.org to report security related issues.

View file

@ -1,39 +1,29 @@
#!/bin/sh #!/bin/sh
NODE_VERSION="10.20.1" pecho() { printf %s\\n "$*"; }
log() { pecho "$@"; }
error() { log "ERROR: $@" >&2; }
fatal() { error "$@"; exit 1; }
is_cmd() { command -v "$@" >/dev/null 2>&1; }
#Move to the folder where ep-lite is installed # Move to the folder where ep-lite is installed
cd $(dirname $0) cd "$(dirname "$0")"/..
#Was this script started in the bin folder? if yes move out # Is wget installed?
if [ -d "../bin" ]; then is_cmd wget || fatal "Please install wget"
cd "../"
fi
#Is wget installed? # Is zip installed?
hash wget > /dev/null 2>&1 || { is_cmd zip || fatal "Please install zip"
echo "Please install wget" >&2
exit 1
}
#Is zip installed? # Is zip installed?
hash zip > /dev/null 2>&1 || { is_cmd unzip || fatal "Please install unzip"
echo "Please install zip" >&2
exit 1
}
#Is zip installed?
hash unzip > /dev/null 2>&1 || {
echo "Please install unzip" >&2
exit 1
}
START_FOLDER=$(pwd); START_FOLDER=$(pwd);
TMP_FOLDER=$(mktemp -d) TMP_FOLDER=$(mktemp -d)
echo "create a clean environment in $TMP_FOLDER..." log "create a clean environment in $TMP_FOLDER..."
cp -ar . $TMP_FOLDER cp -ar . "$TMP_FOLDER"
cd $TMP_FOLDER cd "$TMP_FOLDER"
rm -rf node_modules rm -rf node_modules
rm -f etherpad-lite-win.zip rm -f etherpad-lite-win.zip
@ -41,33 +31,33 @@ rm -f etherpad-lite-win.zip
# making the windows package smaller # making the windows package smaller
export NODE_ENV=production export NODE_ENV=production
echo "do a normal unix install first..." log "do a normal unix install first..."
bin/installDeps.sh || exit 1 bin/installDeps.sh || exit 1
echo "copy the windows settings template..." log "copy the windows settings template..."
cp settings.json.template settings.json cp settings.json.template settings.json
echo "resolve symbolic links..." log "resolve symbolic links..."
cp -rL node_modules node_modules_resolved cp -rL node_modules node_modules_resolved
rm -rf node_modules rm -rf node_modules
mv node_modules_resolved node_modules mv node_modules_resolved node_modules
echo "download windows node..." log "download windows node..."
cd bin cd bin
wget "https://nodejs.org/dist/v$NODE_VERSION/win-x86/node.exe" -O ../node.exe wget "https://nodejs.org/dist/latest-erbium/win-x86/node.exe" -O ../node.exe
echo "remove git history to reduce folder size" log "remove git history to reduce folder size"
rm -rf .git/objects rm -rf .git/objects
echo "remove windows jsdom-nocontextify/test folder" log "remove windows jsdom-nocontextify/test folder"
rm -rf $TMP_FOLDER/src/node_modules/wd/node_modules/request/node_modules/form-data/node_modules/combined-stream/test rm -rf "$TMP_FOLDER"/src/node_modules/wd/node_modules/request/node_modules/form-data/node_modules/combined-stream/test
rm -rf $TMP_FOLDER/src/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/encodings/tables rm -rf "$TMP_FOLDER"/src/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/encodings/tables
echo "create the zip..." log "create the zip..."
cd $TMP_FOLDER cd "$TMP_FOLDER"
zip -9 -r $START_FOLDER/etherpad-lite-win.zip ./* zip -9 -r "$START_FOLDER"/etherpad-lite-win.zip ./*
echo "clean up..." log "clean up..."
rm -rf $TMP_FOLDER rm -rf "$TMP_FOLDER"
echo "Finished. You can find the zip in the Etherpad root folder, it's called etherpad-lite-win.zip" log "Finished. You can find the zip in the Etherpad root folder, it's called etherpad-lite-win.zip"

View file

@ -349,7 +349,7 @@ function convertPad(padId, callback)
//generate new author values //generate new author values
var authorID = "a." + randomString(16); var authorID = "a." + randomString(16);
var authorColorID = authors[i].colorId || Math.floor(Math.random()*32); var authorColorID = authors[i].colorId || Math.floor(Math.random()*(exports.getColorPalette().length));
var authorName = authors[i].name || null; var authorName = authors[i].name || null;
//overwrite the authorID of the attribute pool //overwrite the authorID of the attribute pool

47
bin/createUserSession.js Normal file
View file

@ -0,0 +1,47 @@
/*
* A tool for generating a test user session which can be used for debugging configs
* that require sessions.
*/
const m = (f) => __dirname + '/../' + f;
const fs = require('fs');
const path = require('path');
const querystring = require('querystring');
const request = require(m('src/node_modules/request'));
const settings = require(m('src/node/utils/Settings'));
const supertest = require(m('src/node_modules/supertest'));
(async () => {
const api = supertest('http://'+settings.ip+':'+settings.port);
const filePath = path.join(__dirname, '../APIKEY.txt');
const apikey = fs.readFileSync(filePath, {encoding: 'utf-8'});
let res;
res = await api.get('/api/');
const apiVersion = res.body.currentVersion;
if (!apiVersion) throw new Error('No version set in API');
const uri = (cmd, args) => `/api/${apiVersion}/${cmd}?${querystring.stringify(args)}`;
res = await api.post(uri('createGroup', {apikey}));
if (res.body.code === 1) throw new Error(`Error creating group: ${res.body}`);
const groupID = res.body.data.groupID;
console.log('groupID', groupID);
res = await api.post(uri('createGroupPad', {apikey, groupID}));
if (res.body.code === 1) throw new Error(`Error creating group pad: ${res.body}`);
console.log('Test Pad ID ====> ', res.body.data.padID);
res = await api.post(uri('createAuthor', {apikey}));
if (res.body.code === 1) throw new Error(`Error creating author: ${res.body}`);
const authorID = res.body.data.authorID;
console.log('authorID', authorID);
const validUntil = Math.floor(new Date() / 1000) + 60000;
console.log('validUntil', validUntil);
res = await api.post(uri('createSession', {apikey, groupID, authorID, validUntil}));
if (res.body.code === 1) throw new Error(`Error creating session: ${res.body}`);
console.log('Session made: ====> create a cookie named sessionID and set the value to',
res.body.data.sessionID);
})();

View file

@ -1,20 +1,15 @@
#!/bin/sh #!/bin/sh
#Move to the folder where ep-lite is installed # Move to the folder where ep-lite is installed
cd $(dirname $0) cd "$(dirname "$0")"/..
#Was this script started in the bin folder? if yes move out # Prepare the environment
if [ -d "../bin" ]; then
cd "../"
fi
#Prepare the environment
bin/installDeps.sh || exit 1 bin/installDeps.sh || exit 1
echo "If you are new to debugging Node.js with Chrome DevTools, take a look at this page:" echo "If you are new to debugging Node.js with Chrome DevTools, take a look at this page:"
echo "https://medium.com/@paul_irish/debugging-node-js-nightlies-with-chrome-devtools-7c4a1b95ae27" echo "https://medium.com/@paul_irish/debugging-node-js-nightlies-with-chrome-devtools-7c4a1b95ae27"
echo "Open 'chrome://inspect' on Chrome to start debugging." echo "Open 'chrome://inspect' on Chrome to start debugging."
#Use 0.0.0.0 to allow external connections to the debugger # Use 0.0.0.0 to allow external connections to the debugger
#(ex: running Etherpad on a docker container). Use default port # (9229) # (ex: running Etherpad on a docker container). Use default port # (9229)
node --inspect=0.0.0.0:9229 node_modules/ep_etherpad-lite/node/server.js "$@" node --inspect=0.0.0.0:9229 node_modules/ep_etherpad-lite/node/server.js "$@"

View file

@ -0,0 +1,51 @@
/*
* A tool for deleting ALL GROUP sessions Etherpad user sessions from the CLI,
* because sometimes a brick is required to fix a face.
*/
const request = require('../src/node_modules/request');
const settings = require(__dirname+'/../tests/container/loadSettings').loadSettings();
const supertest = require(__dirname+'/../src/node_modules/supertest');
const api = supertest('http://'+settings.ip+":"+settings.port);
const path = require('path');
const fs = require('fs');
// get the API Key
var filePath = path.join(__dirname, '../APIKEY.txt');
var apikey = fs.readFileSync(filePath, {encoding: 'utf-8'});
// Set apiVersion to base value, we change this later.
var apiVersion = 1;
var guids;
// Update the apiVersion
api.get('/api/')
.expect(function(res){
apiVersion = res.body.currentVersion;
if (!res.body.currentVersion) throw new Error("No version set in API");
return;
})
.then(function(){
let guri = '/api/'+apiVersion+'/listAllGroups?apikey='+apikey;
api.get(guri)
.then(function(res){
guids = res.body.data.groupIDs;
guids.forEach(function(groupID){
let luri = '/api/'+apiVersion+'/listSessionsOfGroup?apikey='+apikey + "&groupID="+groupID;
api.get(luri)
.then(function(res){
if(res.body.data){
Object.keys(res.body.data).forEach(function(sessionID){
if(sessionID){
console.log("Deleting", sessionID);
let duri = '/api/'+apiVersion+'/deleteSession?apikey='+apikey + "&sessionID="+sessionID;
api.post(duri); // deletes
}
})
}else{
// no session in this group.
}
})
})
})
})

View file

@ -4,7 +4,7 @@
*/ */
const request = require('../src/node_modules/request'); const request = require('../src/node_modules/request');
const settings = require(__dirname+'/../tests/backend/loadSettings').loadSettings(); const settings = require(__dirname+'/../tests/container/loadSettings').loadSettings();
const supertest = require(__dirname+'/../src/node_modules/supertest'); const supertest = require(__dirname+'/../src/node_modules/supertest');
const api = supertest('http://'+settings.ip+":"+settings.port); const api = supertest('http://'+settings.ip+":"+settings.port);
const path = require('path'); const path = require('path');

View file

@ -8,6 +8,12 @@ REQUIRED_NODE_MINOR=13
REQUIRED_NPM_MAJOR=5 REQUIRED_NPM_MAJOR=5
REQUIRED_NPM_MINOR=5 REQUIRED_NPM_MINOR=5
pecho() { printf %s\\n "$*"; }
log() { pecho "$@"; }
error() { log "ERROR: $@" >&2; }
fatal() { error "$@"; exit 1; }
is_cmd() { command -v "$@" >/dev/null 2>&1; }
require_minimal_version() { require_minimal_version() {
PROGRAM_LABEL="$1" PROGRAM_LABEL="$1"
VERSION_STRING="$2" VERSION_STRING="$2"
@ -16,71 +22,50 @@ require_minimal_version() {
# Flag -s (--only-delimited on GNU cut) ensures no string is returned # Flag -s (--only-delimited on GNU cut) ensures no string is returned
# when there is no match # when there is no match
DETECTED_MAJOR=$(echo $VERSION_STRING | cut -s -d "." -f 1) DETECTED_MAJOR=$(pecho "$VERSION_STRING" | cut -s -d "." -f 1)
DETECTED_MINOR=$(echo $VERSION_STRING | cut -s -d "." -f 2) DETECTED_MINOR=$(pecho "$VERSION_STRING" | cut -s -d "." -f 2)
if [ -z "$DETECTED_MAJOR" ]; then [ -n "$DETECTED_MAJOR" ] || fatal "Cannot extract $PROGRAM_LABEL major version from version string \"$VERSION_STRING\""
printf 'Cannot extract %s major version from version string "%s"\n' "$PROGRAM_LABEL" "$VERSION_STRING" >&2
exit 1
fi
if [ -z "$DETECTED_MINOR" ]; then [ -n "$DETECTED_MINOR" ] || fatal "Cannot extract $PROGRAM_LABEL minor version from version string \"$VERSION_STRING\""
printf 'Cannot extract %s minor version from version string "%s"\n' "$PROGRAM_LABEL" "$VERSION_STRING" >&2
exit 1
fi
case "$DETECTED_MAJOR" in case "$DETECTED_MAJOR" in
''|*[!0-9]*) ''|*[!0-9]*)
printf '%s major version from "%s" is not a number. Detected: "%s"\n' "$PROGRAM_LABEL" "$VERSION_STRING" "$DETECTED_MAJOR" >&2 fatal "$PROGRAM_LABEL major version from \"$VERSION_STRING\" is not a number. Detected: \"$DETECTED_MAJOR\""
exit 1
;; ;;
esac esac
case "$DETECTED_MINOR" in case "$DETECTED_MINOR" in
''|*[!0-9]*) ''|*[!0-9]*)
printf '%s minor version from "%s" is not a number. Detected: "%s"\n' "$PROGRAM_LABEL" "$VERSION_STRING" "$DETECTED_MINOR" >&2 fatal "$PROGRAM_LABEL minor version from \"$VERSION_STRING\" is not a number. Detected: \"$DETECTED_MINOR\""
exit 1
esac esac
if [ "$DETECTED_MAJOR" -lt "$REQUIRED_MAJOR" ] || ([ "$DETECTED_MAJOR" -eq "$REQUIRED_MAJOR" ] && [ "$DETECTED_MINOR" -lt "$REQUIRED_MINOR" ]); then [ "$DETECTED_MAJOR" -gt "$REQUIRED_MAJOR" ] || ([ "$DETECTED_MAJOR" -eq "$REQUIRED_MAJOR" ] && [ "$DETECTED_MINOR" -ge "$REQUIRED_MINOR" ]) \
printf 'Your %s version "%s" is too old. %s %d.%d.x or higher is required.\n' "$PROGRAM_LABEL" "$VERSION_STRING" "$PROGRAM_LABEL" "$REQUIRED_MAJOR" "$REQUIRED_MINOR" >&2 || fatal "Your $PROGRAM_LABEL version \"$VERSION_STRING\" is too old. $PROGRAM_LABEL $REQUIRED_MAJOR.$REQUIRED_MINOR.x or higher is required."
exit 1
fi
} }
#Move to the folder where ep-lite is installed # Move to the folder where ep-lite is installed
cd $(dirname $0) cd "$(dirname "$0")"/..
#Was this script started in the bin folder? if yes move out # Is node installed?
if [ -d "../bin" ]; then # Not checking io.js, default installation creates a symbolic link to node
cd "../" is_cmd node || fatal "Please install node.js ( https://nodejs.org )"
fi
#Is node installed? # Is npm installed?
#Not checking io.js, default installation creates a symbolic link to node is_cmd npm || fatal "Please install npm ( https://npmjs.org )"
hash node > /dev/null 2>&1 || {
echo "Please install node.js ( https://nodejs.org )" >&2
exit 1
}
#Is npm installed? # Check npm version
hash npm > /dev/null 2>&1 || {
echo "Please install npm ( https://npmjs.org )" >&2
exit 1
}
#Check npm version
NPM_VERSION_STRING=$(npm --version) NPM_VERSION_STRING=$(npm --version)
require_minimal_version "npm" "$NPM_VERSION_STRING" "$REQUIRED_NPM_MAJOR" "$REQUIRED_NPM_MINOR" require_minimal_version "npm" "$NPM_VERSION_STRING" "$REQUIRED_NPM_MAJOR" "$REQUIRED_NPM_MINOR"
#Check node version # Check node version
NODE_VERSION_STRING=$(node --version) NODE_VERSION_STRING=$(node --version)
NODE_VERSION_STRING=${NODE_VERSION_STRING#"v"} NODE_VERSION_STRING=${NODE_VERSION_STRING#"v"}
require_minimal_version "nodejs" "$NODE_VERSION_STRING" "$REQUIRED_NODE_MAJOR" "$REQUIRED_NODE_MINOR" require_minimal_version "nodejs" "$NODE_VERSION_STRING" "$REQUIRED_NODE_MAJOR" "$REQUIRED_NODE_MINOR"
#Get the name of the settings file # Get the name of the settings file
settings="settings.json" settings="settings.json"
a=''; a='';
for arg in "$@"; do for arg in "$@"; do
@ -88,26 +73,26 @@ for arg in "$@"; do
a=$arg a=$arg
done done
#Does a $settings exist? if not copy the template # Does a $settings exist? if not copy the template
if [ ! -f $settings ]; then if [ ! -f "$settings" ]; then
echo "Copy the settings template to $settings..." log "Copy the settings template to $settings..."
cp settings.json.template $settings || exit 1 cp settings.json.template "$settings" || exit 1
fi fi
echo "Ensure that all dependencies are up to date... If this is the first time you have run Etherpad please be patient." log "Ensure that all dependencies are up to date... If this is the first time you have run Etherpad please be patient."
( (
mkdir -p node_modules mkdir -p node_modules
cd node_modules cd node_modules
[ -e ep_etherpad-lite ] || ln -s ../src ep_etherpad-lite [ -e ep_etherpad-lite ] || ln -s ../src ep_etherpad-lite
cd ep_etherpad-lite cd ep_etherpad-lite
npm install --save --loglevel warn npm ci
) || { ) || {
rm -rf src/node_modules rm -rf src/node_modules
exit 1 exit 1
} }
#Remove all minified data to force node creating it new # Remove all minified data to force node creating it new
echo "Clearing minified cache..." log "Clearing minified cache..."
rm -f var/minified* rm -f var/minified*
exit 0 exit 0

View file

@ -14,7 +14,7 @@ cd /D node_modules
mklink /D "ep_etherpad-lite" "..\src" mklink /D "ep_etherpad-lite" "..\src"
cd /D "ep_etherpad-lite" cd /D "ep_etherpad-lite"
cmd /C npm install --loglevel warn || exit /B 1 cmd /C npm ci || exit /B 1
cd /D "%~dp0\.." cd /D "%~dp0\.."

46
bin/plugins/README.md Executable file
View file

@ -0,0 +1,46 @@
The files in this folder are for Plugin developers.
# Get suggestions to improve your Plugin
This code will check your plugin for known usual issues and some suggestions for improvements. No changes will be made to your project.
```
node bin/plugins/checkPlugin.js $PLUGIN_NAME$
```
# Basic Example:
```
node bin/plugins/checkPlugin.js ep_webrtc
```
## Autofixing - will autofix any issues it can
```
node bin/plugins/checkPlugins.js ep_whatever autofix
```
## Autocommitting, push, npm minor patch and npm publish (highly dangerous)
```
node bin/plugins/checkPlugins.js ep_whatever autofix autocommit
```
# All the plugins
Replace johnmclear with your github username
```
# Clones
cd node_modules
GHUSER=johnmclear; curl "https://api.github.com/users/$GHUSER/repos?per_page=1000" | grep -o 'git@[^"]*' | grep /ep_ | xargs -L1 git clone
cd ..
# autofixes and autocommits /pushes & npm publishes
for dir in `ls node_modules`;
do
# echo $0
if [[ $dir == *"ep_"* ]]; then
if [[ $dir != "ep_etherpad-lite" ]]; then
node bin/plugins/checkPlugin.js $dir autofix autocommit
fi
fi
# echo $dir
done
```

246
bin/plugins/checkPlugin.js Executable file
View file

@ -0,0 +1,246 @@
// pro usage for all your plugins, replace johnmclear with your github username
/*
cd node_modules
GHUSER=johnmclear; curl "https://api.github.com/users/$GHUSER/repos?per_page=1000" | grep -o 'git@[^"]*' | grep /ep_ | xargs -L1 git clone
cd ..
for dir in `ls node_modules`;
do
# echo $0
if [[ $dir == *"ep_"* ]]; then
if [[ $dir != "ep_etherpad-lite" ]]; then
node bin/plugins/checkPlugin.js $dir autofix autocommit
fi
fi
# echo $dir
done
*/
/*
*
* Usage
*
* Normal usage: node bin/plugins/checkPlugins.js ep_whatever
* Auto fix the things it can: node bin/plugins/checkPlugins.js ep_whatever autofix
* Auto commit, push and publish(to npm) * highly dangerous:
node bin/plugins/checkPlugins.js ep_whatever autofix autocommit
*/
const fs = require("fs");
const { exec } = require("child_process");
// get plugin name & path from user input
const pluginName = process.argv[2];
const pluginPath = "node_modules/"+pluginName;
console.log("Checking the plugin: "+ pluginName)
// Should we autofix?
if (process.argv[3] && process.argv[3] === "autofix") var autoFix = true;
// Should we update files where possible?
if (process.argv[5] && process.argv[5] === "autoupdate") var autoUpdate = true;
// Should we automcommit and npm publish?!
if (process.argv[4] && process.argv[4] === "autocommit") var autoCommit = true;
if(autoCommit){
console.warn("Auto commit is enabled, I hope you know what you are doing...")
}
fs.readdir(pluginPath, function (err, rootFiles) {
//handling error
if (err) {
return console.log('Unable to scan directory: ' + err);
}
// rewriting files to lower case
var files = [];
// some files we need to know the actual file name. Not compulsory but might help in the future.
var readMeFileName;
var repository;
var hasAutofixed = false;
for (var i = 0; i < rootFiles.length; i++) {
if(rootFiles[i].toLowerCase().indexOf("readme") !== -1) readMeFileName = rootFiles[i];
files.push(rootFiles[i].toLowerCase());
}
if(files.indexOf("package.json") === -1){
console.warn("no package.json, please create");
}
if(files.indexOf("package.json") !== -1){
let packageJSON = fs.readFileSync(pluginPath+"/package.json", {encoding:'utf8', flag:'r'});
if(packageJSON.toLowerCase().indexOf("repository") === -1){
console.warn("No repository in package.json");
if(autoFix){
console.warn("Repository not detected in package.json. Please add repository section manually.")
}
}else{
// useful for creating README later.
repository = JSON.parse(packageJSON).repository.url;
}
}
if(files.indexOf("readme") === -1 && files.indexOf("readme.md") === -1){
console.warn("README.md file not found, please create");
if(autoFix){
console.log("Autofixing missing README.md file, please edit the README.md file further to include plugin specific details.");
let readme = fs.readFileSync("bin/plugins/lib/README.md", {encoding:'utf8', flag:'r'})
readme = readme.replace(/\[plugin_name\]/g, pluginName);
if(repository){
let org = repository.split("/")[3];
let name = repository.split("/")[4];
readme = readme.replace(/\[org_name\]/g, org);
readme = readme.replace(/\[repo_url\]/g, name);
fs.writeFileSync(pluginPath+"/README.md", readme);
}else{
console.warn("Unable to find repository in package.json, aborting.")
}
}
}
if(files.indexOf("readme") !== -1 && files.indexOf("readme.md") !== -1){
let readme = fs.readFileSync(pluginPath+"/"+readMeFileName, {encoding:'utf8', flag:'r'});
if(readme.toLowerCase().indexOf("license") === -1){
console.warn("No license section in README");
if(autoFix){
console.warn("Please add License section to README manually.")
}
}
}
if(files.indexOf("license") === -1 && files.indexOf("license.md") === -1){
console.warn("LICENSE.md file not found, please create");
if(autoFix){
hasAutofixed = true;
console.log("Autofixing missing LICENSE.md file, including Apache 2 license.");
exec("git config user.name", (error, name, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
let license = fs.readFileSync("bin/plugins/lib/LICENSE.md", {encoding:'utf8', flag:'r'});
license = license.replace("[yyyy]", new Date().getFullYear());
license = license.replace("[name of copyright owner]", name)
fs.writeFileSync(pluginPath+"/LICENSE.md", license);
});
}
}
var travisConfig = fs.readFileSync("bin/plugins/lib/travis.yml", {encoding:'utf8', flag:'r'});
travisConfig = travisConfig.replace(/\[plugin_name\]/g, pluginName);
if(files.indexOf(".travis.yml") === -1){
console.warn(".travis.yml file not found, please create. .travis.yml is used for automatically CI testing Etherpad. It is useful to know if your plugin breaks another feature for example.")
// TODO: Make it check version of the .travis file to see if it needs an update.
if(autoFix){
hasAutofixed = true;
console.log("Autofixing missing .travis.yml file");
fs.writeFileSync(pluginPath+"/.travis.yml", travisConfig);
console.log("Travis file created, please sign into travis and enable this repository")
}
}
if(autoFix && autoUpdate){
// checks the file versioning of .travis and updates it to the latest.
let existingConfig = fs.readFileSync(pluginPath + "/.travis.yml", {encoding:'utf8', flag:'r'});
let existingConfigLocation = existingConfig.indexOf("##ETHERPAD_TRAVIS_V=");
let existingValue = existingConfig.substr(existingConfigLocation+20, existingConfig.length);
let newConfigLocation = travisConfig.indexOf("##ETHERPAD_TRAVIS_V=");
let newValue = travisConfig.substr(newConfigLocation+20, travisConfig.length);
if(existingConfigLocation === -1){
console.warn("no previous .travis.yml version found so writing new.")
// we will write the newTravisConfig to the location.
fs.writeFileSync(pluginPath + "/.travis.yml", travisConfig);
}else{
if(newValue > existingValue){
console.log("updating .travis.yml");
fs.writeFileSync(pluginPath + "/.travis.yml", travisConfig);
hasAutofixed = true;
}
}
}
if(files.indexOf(".gitignore") === -1){
console.warn(".gitignore file not found, please create. .gitignore files are useful to ensure files aren't incorrectly commited to a repository.")
if(autoFix){
hasAutofixed = true;
console.log("Autofixing missing .gitignore file");
let gitignore = fs.readFileSync("bin/plugins/lib/gitignore", {encoding:'utf8', flag:'r'});
fs.writeFileSync(pluginPath+"/.gitignore", gitignore);
}
}
if(files.indexOf("locales") === -1){
console.warn("Translations not found, please create. Translation files help with Etherpad accessibility.");
}
if(files.indexOf(".ep_initialized") !== -1){
console.warn(".ep_initialized found, please remove. .ep_initialized should never be commited to git and should only exist once the plugin has been executed one time.")
if(autoFix){
hasAutofixed = true;
console.log("Autofixing incorrectly existing .ep_initialized file");
fs.unlinkSync(pluginPath+"/.ep_initialized");
}
}
if(files.indexOf("npm-debug.log") !== -1){
console.warn("npm-debug.log found, please remove. npm-debug.log should never be commited to your repository.")
if(autoFix){
hasAutofixed = true;
console.log("Autofixing incorrectly existing npm-debug.log file");
fs.unlinkSync(pluginPath+"/npm-debug.log");
}
}
if(files.indexOf("static") !== -1){
fs.readdir(pluginPath+"/static", function (errRead, staticFiles) {
if(staticFiles.indexOf("tests") === -1){
console.warn("Test files not found, please create tests. https://github.com/ether/etherpad-lite/wiki/Creating-a-plugin#writing-and-running-front-end-tests-for-your-plugin")
}
})
}else{
console.warn("Test files not found, please create tests. https://github.com/ether/etherpad-lite/wiki/Creating-a-plugin#writing-and-running-front-end-tests-for-your-plugin")
}
if(hasAutofixed){
console.log("Fixes applied, please check git diff then run the following command:\n\n")
// bump npm Version
if(autoCommit){
// holy shit you brave.
console.log("Attempting autocommit and auto publish to npm")
exec("cd node_modules/"+ pluginName + " && git add -A && git commit --allow-empty -m 'autofixes from Etherpad checkPlugins.js' && npm version patch && git add package.json && git commit --allow-empty -m 'bump version' && git push && npm publish && cd ../..", (error, name, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log("I think she's got it! By George she's got it!")
process.exit(0)
});
}else{
console.log("cd node_modules/"+ pluginName + " && git add -A && git commit --allow-empty -m 'autofixes from Etherpad checkPlugins.js' && npm version patch && git add package.json && git commit --allow-empty -m 'bump version' && git push && npm publish && cd ../..")
}
}
//listing all files using forEach
files.forEach(function (file) {
// Do whatever you want to do with the file
// console.log(file.toLowerCase());
});
});

13
bin/plugins/lib/LICENSE.md Executable file
View file

@ -0,0 +1,13 @@
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

28
bin/plugins/lib/README.md Executable file
View file

@ -0,0 +1,28 @@
[![Travis (.org)](https://api.travis-ci.org/[org_name]/[repo_url].svg?branch=develop)](https://travis-ci.org/github/[org_name]/[repo_url])
# My awesome plugin README example
Explain what your plugin does and who it's useful for.
## Example animated gif of usage if appropriate
## Installing
npm install [plugin_name]
or Use the Etherpad ``/admin`` interface.
## Settings
Document settings if any
## Testing
Document how to run backend / frontend tests.
### Frontend
Visit http://whatever/tests/frontend/ to run the frontend tests.
### backend
Type ``cd src && npm run test`` to run the backend tests.
## LICENSE
Apache 2.0

5
bin/plugins/lib/gitignore Executable file
View file

@ -0,0 +1,5 @@
.ep_initialized
.DS_Store
node_modules/
node_modules
npm-debug.log

68
bin/plugins/lib/travis.yml Executable file
View file

@ -0,0 +1,68 @@
language: node_js
node_js:
- "lts/*"
cache: false
before_install:
- sudo add-apt-repository -y ppa:libreoffice/ppa
- sudo apt-get update
- sudo apt-get -y install libreoffice
- sudo apt-get -y install libreoffice-pdfimport
services:
- docker
install:
- "bin/installDeps.sh"
- "export GIT_HASH=$(git rev-parse --verify --short HEAD)"
before_script:
- "tests/frontend/travis/sauce_tunnel.sh"
script:
- "tests/frontend/travis/runner.sh"
env:
global:
- secure: "WMGxFkOeTTlhWB+ChMucRtIqVmMbwzYdNHuHQjKCcj8HBEPdZLfCuK/kf4rG\nVLcLQiIsyllqzNhBGVHG1nyqWr0/LTm8JRqSCDDVIhpyzp9KpCJQQJG2Uwjk\n6/HIJJh/wbxsEdLNV2crYU/EiVO3A4Bq0YTHUlbhUqG3mSCr5Ec="
- secure: "gejXUAHYscbR6Bodw35XexpToqWkv2ifeECsbeEmjaLkYzXmUUNWJGknKSu7\nEUsSfQV8w+hxApr1Z+jNqk9aX3K1I4btL3cwk2trnNI8XRAvu1c1Iv60eerI\nkE82Rsd5lwUaMEh+/HoL8ztFCZamVndoNgX7HWp5J/NRZZMmh4g="
jobs:
include:
- name: "Run the Backend tests"
install:
- "npm install"
- "mkdir [plugin_name]"
- "mv !([plugin_name]) [plugin_name]"
- "git clone https://github.com/ether/etherpad-lite.git etherpad"
- "cd etherpad"
- "mkdir node_modules"
- "mv ../[plugin_name] node_modules"
- "bin/installDeps.sh"
- "export GIT_HASH=$(git rev-parse --verify --short HEAD)"
- "cd src && npm install && cd -"
script:
- "tests/frontend/travis/runnerBackend.sh"
- name: "Test the Frontend"
install:
- "npm install"
- "mkdir [plugin_name]"
- "mv !([plugin_name]) [plugin_name]"
- "git clone https://github.com/ether/etherpad-lite.git etherpad"
- "cd etherpad"
- "mkdir node_modules"
- "mv ../[plugin_name] node_modules"
- "bin/installDeps.sh"
- "export GIT_HASH=$(git rev-parse --verify --short HEAD)"
script:
- "tests/frontend/travis/runner.sh"
notifications:
irc:
channels:
- "irc.freenode.org#etherpad-lite-dev"
##ETHERPAD_TRAVIS_V=3
## Travis configuration automatically created using bin/plugins/updateAllPluginsScript.sh

14
bin/plugins/reTestAllPlugins.sh Executable file
View file

@ -0,0 +1,14 @@
echo "herp";
for dir in `ls node_modules`;
do
echo $dir
if [[ $dir == *"ep_"* ]]; then
if [[ $dir != "ep_etherpad-lite" ]]; then
# node bin/plugins/checkPlugin.js $dir autofix autocommit autoupdate
cd node_modules/$dir
git commit -m "Automatic update: bump update to re-run latest Etherpad tests" --allow-empty
git push origin master
cd ../..
fi
fi
done

View file

@ -0,0 +1,17 @@
cd node_modules
GHUSER=johnmclear; curl "https://api.github.com/users/$GHUSER/repos?per_page=1000" | grep -o 'git@[^"]*' | grep /ep_ | xargs -L1 git clone
GHUSER=johnmclear; curl "https://api.github.com/users/$GHUSER/repos?per_page=1000&page=2" | grep -o 'git@[^"]*' | grep /ep_ | xargs -L1 git clone
GHUSER=johnmclear; curl "https://api.github.com/users/$GHUSER/repos?per_page=1000&page=3" | grep -o 'git@[^"]*' | grep /ep_ | xargs -L1 git clone
GHUSER=johnmclear; curl "https://api.github.com/users/$GHUSER/repos?per_page=1000&page=4" | grep -o 'git@[^"]*' | grep /ep_ | xargs -L1 git clone
cd ..
for dir in `ls node_modules`;
do
# echo $0
if [[ $dir == *"ep_"* ]]; then
if [[ $dir != "ep_etherpad-lite" ]]; then
node bin/plugins/checkPlugin.js $dir autofix autocommit autoupdate
fi
fi
# echo $dir
done

View file

@ -1,39 +1,37 @@
#!/bin/sh #!/bin/sh
#Move to the folder where ep-lite is installed pecho() { printf %s\\n "$*"; }
cd $(dirname $0) log() { pecho "$@"; }
error() { log "ERROR: $@" >&2; }
fatal() { error "$@"; exit 1; }
#Was this script started in the bin folder? if yes move out # Move to the folder where ep-lite is installed
if [ -d "../bin" ]; then cd "$(dirname "$0")"/..
cd "../"
fi
ignoreRoot=0 ignoreRoot=0
for ARG in "$@" for ARG in "$@"; do
do
if [ "$ARG" = "--root" ]; then if [ "$ARG" = "--root" ]; then
ignoreRoot=1 ignoreRoot=1
fi fi
done done
#Stop the script if it's started as root # Stop the script if it's started as root
if [ "$(id -u)" -eq 0 ] && [ $ignoreRoot -eq 0 ]; then if [ "$(id -u)" -eq 0 ] && [ "$ignoreRoot" -eq 0 ]; then
echo "You shouldn't start Etherpad as root!" cat <<EOF >&2
echo "Please type 'Etherpad rocks my socks' or supply the '--root' argument if you still want to start it as root" You shouldn't start Etherpad as root!
Please type 'Etherpad rocks my socks' (or restart with the '--root'
argument) if you still want to start it as root:
EOF
printf "> " >&2
read rocks read rocks
if [ ! "$rocks" == "Etherpad rocks my socks" ] [ "$rocks" = "Etherpad rocks my socks" ] || fatal "Your input was incorrect"
then
echo "Your input was incorrect"
exit 1
fi
fi fi
#Prepare the environment # Prepare the environment
bin/installDeps.sh "$@" || exit 1 bin/installDeps.sh "$@" || exit 1
#Move to the node folder and start # Move to the node folder and start
echo "Started Etherpad..." log "Starting Etherpad..."
SCRIPTPATH=$(pwd -P) SCRIPTPATH=$(pwd -P)
exec node "$SCRIPTPATH/node_modules/ep_etherpad-lite/node/server.js" "$@" exec node "$SCRIPTPATH/node_modules/ep_etherpad-lite/node/server.js" "$@"

View file

@ -1,10 +1,11 @@
#!/bin/sh #!/bin/sh
#This script ensures that ep-lite is automatically restarting after an error happens # This script ensures that ep-lite is automatically restarting after
# an error happens
#Handling Errors # Handling Errors
# 0 silent # 0 silent
# 1 email # 1 email
ERROR_HANDLING=0 ERROR_HANDLING=0
# Your email address which should receive the error messages # Your email address which should receive the error messages
EMAIL_ADDRESS="no-reply@example.com" EMAIL_ADDRESS="no-reply@example.com"
@ -15,54 +16,54 @@ TIME_BETWEEN_EMAILS=600 # 10 minutes
# DON'T EDIT AFTER THIS LINE # DON'T EDIT AFTER THIS LINE
pecho() { printf %s\\n "$*"; }
log() { pecho "$@"; }
error() { log "ERROR: $@" >&2; }
fatal() { error "$@"; exit 1; }
LAST_EMAIL_SEND=0 LAST_EMAIL_SEND=0
# Move to the folder where ep-lite is installed
cd "$(dirname "$0")"/..
# Check if a logfile parameter is set
LOG="$1" LOG="$1"
[ -n "${LOG}" ] || fatal "Set a logfile as the first parameter"
#Move to the folder where ep-lite is installed
cd $(dirname $0)
#Was this script started in the bin folder? if yes move out
if [ -d "../bin" ]; then
cd "../"
fi
#Check if a logfile parameter is set
if [ -z "${LOG}" ]; then
echo "Set a logfile as the first parameter"
exit 1
fi
shift shift
while [ 1 ]
do
#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 while true; do
if [ ! -w ${LOG} ]; then # Try to touch the file if it doesn't exist
echo "Logfile '${LOG}' is not writeable" [ -f "${LOG}" ] || touch "${LOG}" || fatal "Logfile '${LOG}' is not writeable"
exit 1
fi
#Start the application # Check if the file is writeable
bin/run.sh $@ >>${LOG} 2>>${LOG} [ -w "${LOG}" ] || fatal "Logfile '${LOG}' is not writeable"
#Send email # Start the application
if [ $ERROR_HANDLING = 1 ]; then bin/run.sh "$@" >>${LOG} 2>>${LOG}
TIME_FMT=$(date +%Y-%m-%dT%H:%M:%S%z)
# Send email
if [ "$ERROR_HANDLING" = 1 ]; then
TIME_NOW=$(date +%s) TIME_NOW=$(date +%s)
TIME_SINCE_LAST_SEND=$(($TIME_NOW - $LAST_EMAIL_SEND)) TIME_SINCE_LAST_SEND=$(($TIME_NOW - $LAST_EMAIL_SEND))
if [ $TIME_SINCE_LAST_SEND -gt $TIME_BETWEEN_EMAILS ]; then if [ "$TIME_SINCE_LAST_SEND" -gt "$TIME_BETWEEN_EMAILS" ]; then
printf "Server was restarted at: $(date)\nThe last 50 lines of the log before the error happens:\n $(tail -n 50 ${LOG})" | mail -s "Pad Server was restarted" $EMAIL_ADDRESS {
cat <<EOF
Server was restarted at: ${TIME_FMT}
The last 50 lines of the log before the server exited:
EOF
tail -n 50 "${LOG}"
} | mail -s "Etherpad restarted" "$EMAIL_ADDRESS"
LAST_EMAIL_SEND=$TIME_NOW LAST_EMAIL_SEND=$TIME_NOW
fi fi
fi fi
echo "RESTART!" >>${LOG} pecho "RESTART! ${TIME_FMT}" >>${LOG}
#Sleep 10 seconds before restart # Sleep 10 seconds before restart
sleep 10 sleep 10
done done

View file

@ -1,11 +1,51 @@
# Hooks # Hooks
All hooks are called with two arguments:
1. name - the name of the hook being called A hook function is registered with a hook via the plugin's `ep.json` file. See
2. context - an object with some relevant information about the context of the call the Plugins section for details. A hook may have many registered functions from
different plugins.
When a hook is invoked, its registered functions are called with three
arguments:
1. hookName - The name of the hook being invoked.
2. context - An object with some relevant information about the context of the
call. See the hook-specific documentation for details.
3. callback - Function to call when done. This callback takes a single argument,
the meaning of which depends on the hook. See the "Return values" section for
general information that applies to most hooks. The value returned by this
callback must be returned by the hook function unless otherwise specified.
## Return values ## Return values
A hook should always return a list or undefined. Returning undefined is equivalent to returning an empty list.
All the returned lists are appended to each other, so if the return values where `[1, 2]`, `undefined`, `[3, 4,]`, `undefined` and `[5]`, the value returned by callHook would be `[1, 2, 3, 4, 5]`.
This is, because it should never matter if you have one plugin or several plugins doing some work - a single plugin should be able to make callHook return the same value a set of plugins are able to return collectively. So, any plugin can return a list of values, of any length, not just one value. Note: This section applies to every hook unless the hook-specific documentation
says otherwise.
Hook functions return zero or more values to Etherpad by passing an array to the
provided callback. Hook functions typically provide a single value (array of
length one). If the function does not want to or need to provide a value, it may
pass an empty array or `undefined` (which is treated the same as an empty
array). Hook functions may also provide more than one value (array of length two
or more).
Some hooks concatenate the arrays provided by its registered functions. For
example, if a hook's registered functions pass `[1, 2]`, `undefined`, `[3, 4]`,
`[]`, and `[5]` to the provided callback, then the hook's return value is `[1,
2, 3, 4, 5]`.
Other hooks only use the first non-empty array provided by a registered
function. In this case, each of the hook's registered functions is called one at
a time until one provides a non-empty array. The remaining functions are
skipped. If none of the functions provide a non-empty array, or there are no
registered functions, the hook's return value is `[]`.
Example:
```
exports.abstractHook = (hookName, context, callback) => {
if (notApplicableToThisPlugin(context)) {
return callback();
}
const value = doSomeProcessing(context);
return callback([value]);
};
```

View file

@ -93,7 +93,10 @@ Available blocks in `pad.html` are:
`index.html` blocks: `index.html` blocks:
* `indexCustomStyles` - contains the `index.css` `<link>` tag, allows you to add your own or to customize the one provided by the active skin
* `indexWrapper` - contains the form for creating new pads * `indexWrapper` - contains the form for creating new pads
* `indexCustomScripts` - contains the `index.js` `<script>` tag, allows you to add your own or to customize the one provided by the active skin
* `indexCustomInlineScripts` - contains the inline `<script>` of home page, allows you to customize `go2Name()`, `go2Random()` or `randomPadName()` functions
## padInitToolbar ## padInitToolbar
Called from: src/node/hooks/express/specialpages.js Called from: src/node/hooks/express/specialpages.js
@ -197,7 +200,69 @@ Things in context:
3. next - ? 3. next - ?
4. resource - the path being accessed 4. resource - the path being accessed
This is useful for modifying the way authentication is done, especially for specific paths. This hook is called to handle authorization. It is especially useful for
controlling access to specific paths.
A plugin's authorize function is typically called twice for each access: once
before authentication and again after. Specifically, it is called if all of the
following are true:
* The request is not for static content or an API endpoint. (Requests for static
content and API endpoints are always authorized, even if unauthenticated.)
* Either authentication has not yet been performed (`context.req.session.user`
is undefined) or the user has successfully authenticated
(`context.req.session.user` is an object containing user-specific settings).
* If the user has successfully authenticated, the user is not an admin. (Admin
users are always authorized.)
* Either the request is for an `/admin` page or the `requireAuthentication`
setting is true.
* Either the request is for an `/admin` page, or the user has not yet
authenticated, or the user has authenticated and the `requireAuthorization`
setting is true.
* For pre-authentication invocations of a plugin's authorize function
(`context.req.session.user` is undefined), an authorize function from a
different plugin has not already caused the pre-authentication authorization
to pass or fail.
* For post-authentication invocations of a plugin's authorize function
(`context.req.session.user` is an object), an authorize function from a
different plugin has not already caused the post-authentication authorization
to pass or fail.
For pre-authentication invocations of your authorize function, calling the
provided callback with `[true]` will immediately grant access without requiring
the user to authenticate. Calling the provided callback with `[false]` will
trigger authentication unless authentication is not required. Calling the
provided callback with `[]` or `undefined` will defer the decision to the next
authorization plugin (if any, otherwise it is the same as calling with
`[false]`).
**WARNING:** Your authorize function can be called for an `/admin` page even if
the user has not yet authenticated. It is your responsibility to fail or defer
authorization if you do not want to grant admin privileges to the general
public.
For post-authentication invocations of your authorize function, calling the
provided callback with `[true]` or `[false]` will cause access to be granted or
denied, respectively. Calling the callback with `[]` or `undefined` will defer
the authorization decision to the next authorization plugin (if any, otherwise
deny).
Example:
```
exports.authorize = (hookName, context, cb) => {
const user = context.req.session.user;
if (!user) {
// The user has not yet authenticated so defer the pre-authentication
// authorization decision to the next plugin.
return cb([]);
}
const path = context.req.path; // or context.resource
if (isExplicitlyProhibited(user, path)) return cb([false]);
if (isExplicitlyAllowed(user, path)) return cb([true]);
return cb([]); // Let the next authorization plugin decide
};
```
## authenticate ## authenticate
Called from: src/node/hooks/express/webaccess.js Called from: src/node/hooks/express/webaccess.js
@ -210,7 +275,57 @@ Things in context:
4. username - the username used (optional) 4. username - the username used (optional)
5. password - the password used (optional) 5. password - the password used (optional)
This is useful for modifying the way authentication is done. This hook is called to handle authentication.
Plugins that supply an authenticate function should probably also supply an
authFailure function unless falling back to HTTP basic authentication is
appropriate upon authentication failure.
This hook is only called if either the `requireAuthentication` setting is true
or the request is for an `/admin` page.
Calling the provided callback with `[true]` or `[false]` will cause
authentication to succeed or fail, respectively. Calling the callback with `[]`
or `undefined` will defer the authentication decision to the next authentication
plugin (if any, otherwise fall back to HTTP basic authentication).
If you wish to provide a mix of restricted and anonymous access (e.g., some pads
are private, others are public), you can "authenticate" (as a guest account)
users that have not yet logged in, and rely on other hooks (e.g., authorize,
onAccessCheck, handleMessageSecurity) to authorize specific privileged actions.
If authentication is successful, the authenticate function MUST set
`context.req.session.user` to the user's settings object. The `username`
property of this object should be set to the user's username. The settings
object should come from global settings (`settings.users[username]`).
Example:
```
let global_settings;
exports.loadSettings = (hook_name, {settings}, cb) => {
global_settings = settings;
return cb();
};
exports.authenticate = (hook_name, context, cb) => {
if (notApplicableToThisPlugin(context)) {
return cb([]); // Let the next authentication plugin decide
}
const username = authenticate(context);
if (!username) {
console.warn(`ep_myplugin.authenticate: Failed authentication from IP ${context.req.ip}`);
return cb([false]);
}
console.info(`ep_myplugin.authenticate: Successful authentication from IP ${context.req.ip} for user ${username}`);
const users = global_settings.users;
if (!(username in users)) users[username] = {};
users[username].username = username;
context.req.session.user = users[username];
return cb([true]);
};
```
## authFailure ## authFailure
Called from: src/node/hooks/express/webaccess.js Called from: src/node/hooks/express/webaccess.js
@ -221,7 +336,34 @@ Things in context:
2. res - the response object 2. res - the response object
3. next - ? 3. next - ?
This is useful for modifying the way authentication is done. This hook is called to handle an authentication or authorization failure.
Plugins that supply an authenticate function should probably also supply an
authFailure function unless falling back to HTTP basic authentication is
appropriate upon authentication failure.
A plugin's authFailure function is only called if all of the following are true:
* There was an authentication or authorization failure.
* The failure was not already handled by an authFailure function from another
plugin.
Calling the provided callback with `[true]` tells Etherpad that the failure was
handled and no further error handling is required. Calling the callback with
`[]` or `undefined` defers error handling to the next authFailure plugin (if
any, otherwise fall back to HTTP basic authentication).
Example:
```
exports.authFailure = (hookName, context, cb) => {
if (notApplicableToThisPlugin(context)) {
return cb([]); // Let the next plugin handle the error
}
context.res.redirect(makeLoginURL(context.req));
return cb([true]);
};
```
## handleMessage ## handleMessage
Called from: src/node/handler/PadMessageHandler.js Called from: src/node/handler/PadMessageHandler.js
@ -275,7 +417,6 @@ function handleMessageSecurity ( hook, context, callback ) {
}; };
``` ```
## clientVars ## clientVars
Called from: src/node/handler/PadMessageHandler.js Called from: src/node/handler/PadMessageHandler.js
@ -283,16 +424,38 @@ Things in context:
1. clientVars - the basic `clientVars` built by the core 1. clientVars - the basic `clientVars` built by the core
2. pad - the pad this session is about 2. pad - the pad this session is about
3. socket - the socket.io Socket object
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`. This hook is called after a client connects but before the initial configuration
is sent to the client. Plugins can use this hook to manipulate the
configuration. (Example: Add a tracking ID for an external analytics tool that
is used client-side.)
Example: The clientVars function must return a Promise that resolves to an object (or
null/undefined) whose properties will be merged into `context.clientVars`.
Returning `callback(value)` will return a Promise that is resolved to `value`.
You can modify `context.clientVars` to change the values sent to the client, but
beware: async functions from other clientVars plugins might also be reading or
manipulating the same `context.clientVars` object. For this reason it is
recommended you return an object rather than modify `context.clientVars`.
If needed, you can access the user's account information (if authenticated) via
`context.socket.client.request.session.user`.
Examples:
``` ```
exports.clientVars = function(hook, context, callback) // Using an async function
{ exports.clientVars = async (hookName, context) => {
// tell the client which year we are in const user = context.socket.client.request.session.user || {};
return callback({ "currentYear": new Date().getFullYear() }); return {'accountUsername': user.username || '<unknown>'}
};
// Using a regular function
exports.clientVars = (hookName, context, callback) => {
const user = context.socket.client.request.session.user || {};
return callback({'accountUsername': user.username || '<unknown>'});
}; };
``` ```

View file

@ -92,3 +92,23 @@ For example, if you want to replace `Chat` with `Notes`, simply add...
, "pad.chat": "Notes" , "pad.chat": "Notes"
} }
``` ```
## Customization for Administrators
As an Etherpad administrator, it is possible to overwrite core mesages as well as messages in plugins. These include error messages, labels, and user instructions. Whereas the localization in the source code is in separate files separated by locale, an administrator's custom localizations are in `settings.json` under the `customLocaleStrings` key, with each locale separated by a sub-key underneath.
For example, let's say you want to change the text on the "New Pad" button on Etherpad's home page. If you look in `locales/en.json` (or `locales/en-gb.json`) you'll see the key for this text is `"index.newPad"`. You could add the following to `settings.json`:
```
"customLocaleStrings": {
"fr": {
"index.newPad": "Créer un document"
},
"en-gb": {
"index.newPad": "Create a document"
},
"en": {
"index.newPad": "Create a document"
}
}
```

View file

@ -551,5 +551,8 @@
*/ */
] ]
} // logconfig }, // logconfig
/* Override any strings found in locale directories */
"customLocaleStrings": {}
} }

View file

@ -467,6 +467,36 @@
*/ */
"importMaxFileSize": 52428800, // 50 * 1024 * 1024 "importMaxFileSize": 52428800, // 50 * 1024 * 1024
/*
* From Etherpad 1.8.3 onwards import was restricted to authors who had
* content within the pad.
*
* This setting will override that restriction and allow any user to import
* without the requirement to add content to a pad.
*
* This setting is useful for when you use a plugin for authentication so you
* can already trust each user.
*/
"allowAnyoneToImport": false,
/*
* From Etherpad 1.9.0 onwards, when Etherpad is in production mode commits from individual users are rate limited
*
* The default is to allow at most 10 changes per IP in a 1 second window.
* After that the change is rejected.
*
* See https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#websocket-single-connection-prevent-flooding for more options
*/
"commitRateLimiting": {
// duration of the rate limit window (seconds)
"duration": 1,
// maximum number of chanes per IP to allow during the rate limit window
"points": 10
},
/* /*
* Toolbar buttons configuration. * Toolbar buttons configuration.
* *
@ -556,5 +586,8 @@
*/ */
] ]
} // logconfig }, // logconfig
/* Override any strings found in locale directories */
"customLocaleStrings": {}
} }

View file

@ -16,6 +16,7 @@
}, },
"index.newPad": "باد جديد", "index.newPad": "باد جديد",
"index.createOpenPad": "أو صنع/فتح باد بوضع اسمه:", "index.createOpenPad": "أو صنع/فتح باد بوضع اسمه:",
"index.openPad": "افتح باد موجودة بالاسم:",
"pad.toolbar.bold.title": "سميك (Ctrl+B)", "pad.toolbar.bold.title": "سميك (Ctrl+B)",
"pad.toolbar.italic.title": "مائل (Ctrl+I)", "pad.toolbar.italic.title": "مائل (Ctrl+I)",
"pad.toolbar.underline.title": "تسطير (Ctrl+U)", "pad.toolbar.underline.title": "تسطير (Ctrl+U)",
@ -50,6 +51,8 @@
"pad.settings.fontType": "نوع الخط:", "pad.settings.fontType": "نوع الخط:",
"pad.settings.fontType.normal": "عادي", "pad.settings.fontType.normal": "عادي",
"pad.settings.language": "اللغة:", "pad.settings.language": "اللغة:",
"pad.settings.about": "حول",
"pad.settings.poweredBy": "مدعوم من",
"pad.importExport.import_export": "استيراد/تصدير", "pad.importExport.import_export": "استيراد/تصدير",
"pad.importExport.import": "تحميل أي ملف نصي أو وثيقة", "pad.importExport.import": "تحميل أي ملف نصي أو وثيقة",
"pad.importExport.importSuccessful": "ناجح!", "pad.importExport.importSuccessful": "ناجح!",
@ -60,7 +63,7 @@
"pad.importExport.exportword": "مايكروسوفت وورد", "pad.importExport.exportword": "مايكروسوفت وورد",
"pad.importExport.exportpdf": "صيغة المستندات المحمولة", "pad.importExport.exportpdf": "صيغة المستندات المحمولة",
"pad.importExport.exportopen": "ODF (نسق المستند المفتوح)", "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-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 أو LibreOffice</a>.",
"pad.modals.connected": "متصل.", "pad.modals.connected": "متصل.",
"pad.modals.reconnecting": "إعادة الاتصال ببادك..", "pad.modals.reconnecting": "إعادة الاتصال ببادك..",
"pad.modals.forcereconnect": "فرض إعادة الاتصال", "pad.modals.forcereconnect": "فرض إعادة الاتصال",

View file

@ -6,6 +6,7 @@
}, },
"index.newPad": "Nuevu bloc", "index.newPad": "Nuevu bloc",
"index.createOpenPad": "o crear/abrir un bloc col nome:", "index.createOpenPad": "o crear/abrir un bloc col nome:",
"index.openPad": "abre un bloc qu'esiste col nome:",
"pad.toolbar.bold.title": "Negrina (Ctrl-B)", "pad.toolbar.bold.title": "Negrina (Ctrl-B)",
"pad.toolbar.italic.title": "Cursiva (Ctrl-I)", "pad.toolbar.italic.title": "Cursiva (Ctrl-I)",
"pad.toolbar.underline.title": "Sorrayáu (Ctrl-U)", "pad.toolbar.underline.title": "Sorrayáu (Ctrl-U)",
@ -26,7 +27,7 @@
"pad.colorpicker.save": "Guardar", "pad.colorpicker.save": "Guardar",
"pad.colorpicker.cancel": "Encaboxar", "pad.colorpicker.cancel": "Encaboxar",
"pad.loading": "Cargando...", "pad.loading": "Cargando...",
"pad.noCookie": "Nun pudo alcontrase la cookie. ¡Por favor, permite les cookies nel navegador!", "pad.noCookie": "Nun pudo alcontrase la cookie. ¡Por favor, permite les cookies nel navegador! La sesión y preferencies nun se guarden ente visites. Esto pué debese a qu'Etherpad inclúyese nun iFrame en dalgunos restoladores. Asegúrate de qu'Etherpad tea nel mesmu subdominiu/dominiu que la iFrame padre",
"pad.passwordRequired": "Necesites una contraseña pa entrar a esti bloc", "pad.passwordRequired": "Necesites una contraseña pa entrar a esti bloc",
"pad.permissionDenied": "Nun tienes permisu pa entrar a esti bloc", "pad.permissionDenied": "Nun tienes permisu pa entrar a esti bloc",
"pad.wrongPassword": "La contraseña era incorreuta", "pad.wrongPassword": "La contraseña era incorreuta",
@ -40,6 +41,8 @@
"pad.settings.fontType": "Tipografía:", "pad.settings.fontType": "Tipografía:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Llingua:", "pad.settings.language": "Llingua:",
"pad.settings.about": "Tocante a",
"pad.settings.poweredBy": "Col encontu de",
"pad.importExport.import_export": "Importar/Esportar", "pad.importExport.import_export": "Importar/Esportar",
"pad.importExport.import": "Xubir cualquier ficheru o documentu de testu", "pad.importExport.import": "Xubir cualquier ficheru o documentu de testu",
"pad.importExport.importSuccessful": "¡Correuto!", "pad.importExport.importSuccessful": "¡Correuto!",

View file

@ -7,6 +7,7 @@
"Mastizada", "Mastizada",
"Mushviq Abdulla", "Mushviq Abdulla",
"Neriman2003", "Neriman2003",
"Vesely35",
"Wertuose" "Wertuose"
] ]
}, },
@ -46,6 +47,8 @@
"pad.settings.fontType": "Şriftin tipi:", "pad.settings.fontType": "Şriftin tipi:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Dil:", "pad.settings.language": "Dil:",
"pad.settings.about": "Haqqında",
"pad.settings.poweredBy": "$1 ilə işləyir",
"pad.importExport.import_export": "İdxal/İxrac", "pad.importExport.import_export": "İdxal/İxrac",
"pad.importExport.import": "Hər hansı bir mətn faylı və ya sənəd yüklə", "pad.importExport.import": "Hər hansı bir mətn faylı və ya sənəd yüklə",
"pad.importExport.importSuccessful": "Uğurlu!", "pad.importExport.importSuccessful": "Uğurlu!",

View file

@ -3,11 +3,13 @@
"authors": [ "authors": [
"Jim-by", "Jim-by",
"Red Winged Duck", "Red Winged Duck",
"Renessaince",
"Wizardist" "Wizardist"
] ]
}, },
"index.newPad": "Стварыць", "index.newPad": "Стварыць",
"index.createOpenPad": "ці тварыць/адкрыць дакумэнт з назвай:", "index.createOpenPad": "ці тварыць/адкрыць дакумэнт з назвай:",
"index.openPad": "адкрыць існы Нататнік з назваю:",
"pad.toolbar.bold.title": "Тоўсты (Ctrl-B)", "pad.toolbar.bold.title": "Тоўсты (Ctrl-B)",
"pad.toolbar.italic.title": "Курсіў (Ctrl-I)", "pad.toolbar.italic.title": "Курсіў (Ctrl-I)",
"pad.toolbar.underline.title": "Падкрэсьліваньне (Ctrl-U)", "pad.toolbar.underline.title": "Падкрэсьліваньне (Ctrl-U)",
@ -28,7 +30,7 @@
"pad.colorpicker.save": "Захаваць", "pad.colorpicker.save": "Захаваць",
"pad.colorpicker.cancel": "Скасаваць", "pad.colorpicker.cancel": "Скасаваць",
"pad.loading": "Загрузка...", "pad.loading": "Загрузка...",
"pad.noCookie": "Кукі ня знойдзеныя. Калі ласка, дазвольце кукі ў вашым браўзэры!", "pad.noCookie": "Кукі ня знойдзеныя. Калі ласка, дазвольце кукі ў вашым браўзэры! Паміж наведваньнямі вашая сэсія і налады ня будуць захаваныя. Гэта можа адбывацца таму, што ў некаторых броўзэрах Etherpad заключаны ўнутры iFrame. Праверце, калі ласка, што Etherpad знаходзіцца ў тым жа паддамэне/дамэне, што і бацькоўскі iFrame",
"pad.passwordRequired": "Для доступу да гэтага дакумэнта патрэбны пароль", "pad.passwordRequired": "Для доступу да гэтага дакумэнта патрэбны пароль",
"pad.permissionDenied": "Вы ня маеце дазволу на доступ да гэтага дакумэнта", "pad.permissionDenied": "Вы ня маеце дазволу на доступ да гэтага дакумэнта",
"pad.wrongPassword": "Вы ўвялі няслушны пароль", "pad.wrongPassword": "Вы ўвялі няслушны пароль",
@ -52,7 +54,7 @@
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)", "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.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 альбо LibreOffice</a>.",
"pad.modals.connected": "Падлучыліся.", "pad.modals.connected": "Падлучыліся.",
"pad.modals.reconnecting": "Перападлучэньне да вашага дакумэнта...", "pad.modals.reconnecting": "Перападлучэньне да вашага дакумэнта...",
"pad.modals.forcereconnect": "Прымусовае перападлучэньне", "pad.modals.forcereconnect": "Прымусовае перападлучэньне",
@ -120,7 +122,7 @@
"pad.userlist.guest": "Госьць", "pad.userlist.guest": "Госьць",
"pad.userlist.deny": "Адхіліць", "pad.userlist.deny": "Адхіліць",
"pad.userlist.approve": "Зацьвердзіць", "pad.userlist.approve": "Зацьвердзіць",
"pad.editbar.clearcolors": "Ачысьціць аўтарскія колеры ва ўсім дакумэнце?", "pad.editbar.clearcolors": "Ачысьціць аўтарскія колеры ва ўсім дакумэнце? Гэта немагчыма будзе скасаваць",
"pad.impexp.importbutton": "Імпартаваць зараз", "pad.impexp.importbutton": "Імпартаваць зараз",
"pad.impexp.importing": "Імпартаваньне…", "pad.impexp.importing": "Імпартаваньне…",
"pad.impexp.confirmimport": "Імпарт файла перазапіша цяперашні тэкст дакумэнту. Вы ўпэўненыя, што хочаце працягваць?", "pad.impexp.confirmimport": "Імпарт файла перазапіша цяперашні тэкст дакумэнту. Вы ўпэўненыя, што хочаце працягваць?",
@ -129,5 +131,7 @@
"pad.impexp.uploadFailed": "Загрузка не атрымалася, калі ласка, паспрабуйце яшчэ раз", "pad.impexp.uploadFailed": "Загрузка не атрымалася, калі ласка, паспрабуйце яшчэ раз",
"pad.impexp.importfailed": "Памылка імпарту", "pad.impexp.importfailed": "Памылка імпарту",
"pad.impexp.copypaste": "Калі ласка, скапіюйце і ўстаўце", "pad.impexp.copypaste": "Калі ласка, скапіюйце і ўстаўце",
"pad.impexp.exportdisabled": "Экспарт у фармаце {{type}} адключаны. Калі ласка, зьвярніцеся да вашага сыстэмнага адміністратара па падрабязнасьці." "pad.impexp.exportdisabled": "Экспарт у фармаце {{type}} адключаны. Калі ласка, зьвярніцеся да вашага сыстэмнага адміністратара па падрабязнасьці.",
"pad.impexp.maxFileSize": "Файл завялікі. Зьвярніцеся да адміністратара сайту, каб павялічыць дазволены памер файлаў для імпарту",
"pad.impexp.permission": "Імпарт адключаны, бо вы ніколі не працавалі з гэтым нататнікам. Калі ласка, перад імпартам зрабеце хоць бы адзін унёсак"
} }

View file

@ -6,6 +6,7 @@
"Bellayet", "Bellayet",
"Nasir8891", "Nasir8891",
"Sankarshan", "Sankarshan",
"Sibabrata Banerjee",
"আফতাবুজ্জামান" "আফতাবুজ্জামান"
] ]
}, },
@ -45,6 +46,8 @@
"pad.settings.fontType": "ফন্টের প্রকার:", "pad.settings.fontType": "ফন্টের প্রকার:",
"pad.settings.fontType.normal": "সাধারণ", "pad.settings.fontType.normal": "সাধারণ",
"pad.settings.language": "ভাষা:", "pad.settings.language": "ভাষা:",
"pad.settings.about": "পরিচিতি",
"pad.settings.poweredBy": "$1 দ্বারা চালিত",
"pad.importExport.import_export": "আমদানি/রপ্তানি", "pad.importExport.import_export": "আমদানি/রপ্তানি",
"pad.importExport.import": "কোন টেক্সট ফাইল বা নথি আপলোড করুন", "pad.importExport.import": "কোন টেক্সট ফাইল বা নথি আপলোড করুন",
"pad.importExport.importSuccessful": "সফল!", "pad.importExport.importSuccessful": "সফল!",

View file

@ -3,7 +3,8 @@
"authors": [ "authors": [
"Edinwiki", "Edinwiki",
"Semina x", "Semina x",
"Srdjan m" "Srdjan m",
"Srđan"
] ]
}, },
"index.newPad": "Novi Pad", "index.newPad": "Novi Pad",

View file

@ -6,6 +6,7 @@
"Jaumeortola", "Jaumeortola",
"Joan manel", "Joan manel",
"Macofe", "Macofe",
"Mguix",
"Pginer", "Pginer",
"Pitort", "Pitort",
"Ssola", "Ssola",
@ -14,6 +15,7 @@
}, },
"index.newPad": "Nou pad", "index.newPad": "Nou pad",
"index.createOpenPad": "o crea/obre un pad amb el nom:", "index.createOpenPad": "o crea/obre un pad amb el nom:",
"index.openPad": "obrir un Pad existint amb el nom:",
"pad.toolbar.bold.title": "Negreta (Ctrl-B)", "pad.toolbar.bold.title": "Negreta (Ctrl-B)",
"pad.toolbar.italic.title": "Cursiva (Ctrl-I)", "pad.toolbar.italic.title": "Cursiva (Ctrl-I)",
"pad.toolbar.underline.title": "Subratllat (Ctrl-U)", "pad.toolbar.underline.title": "Subratllat (Ctrl-U)",
@ -48,6 +50,8 @@
"pad.settings.fontType": "Tipus de lletra:", "pad.settings.fontType": "Tipus de lletra:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Llengua:", "pad.settings.language": "Llengua:",
"pad.settings.about": "Sobre",
"pad.settings.poweredBy": "Funciona amb",
"pad.importExport.import_export": "Importació/exportació", "pad.importExport.import_export": "Importació/exportació",
"pad.importExport.import": "Puja qualsevol fitxer de text o document", "pad.importExport.import": "Puja qualsevol fitxer de text o document",
"pad.importExport.importSuccessful": "Hi ha hagut èxit!", "pad.importExport.importSuccessful": "Hi ha hagut èxit!",
@ -58,7 +62,7 @@
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)", "pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Només podeu importar de text net o HTML. Per a opcions d'importació més avançades <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instal·leu l'Abiword</a>.", "pad.importExport.abiword.innerHTML": "Només podeu importar de text sense format o HTML. Per a opcions d'importació més avançades <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instal·leu l'Abiword</a>.",
"pad.modals.connected": "Connectat.", "pad.modals.connected": "Connectat.",
"pad.modals.reconnecting": "S'està tornant a connectar al vostre pad…", "pad.modals.reconnecting": "S'està tornant a connectar al vostre pad…",
"pad.modals.forcereconnect": "Força tornar a connectar", "pad.modals.forcereconnect": "Força tornar a connectar",
@ -82,6 +86,8 @@
"pad.modals.corruptPad.cause": "Això pot ser degut a una configuració errònia del servidor o a algun altre comportament inesperat. Si us plau, contacteu amb l'administrador del servei.", "pad.modals.corruptPad.cause": "Això pot ser degut a una configuració errònia del servidor o a algun altre comportament inesperat. Si us plau, contacteu amb l'administrador del servei.",
"pad.modals.deleted": "Suprimit.", "pad.modals.deleted": "Suprimit.",
"pad.modals.deleted.explanation": "S'ha suprimit el pad.", "pad.modals.deleted.explanation": "S'ha suprimit el pad.",
"pad.modals.rateLimited": "Tarifa limitada.",
"pad.modals.rateLimited.explanation": "Heu enviat massa missatges a aquest pad per això us han desconnectat.",
"pad.modals.disconnected": "Heu estat desconnectat.", "pad.modals.disconnected": "Heu estat desconnectat.",
"pad.modals.disconnected.explanation": "S'ha perdut la connexió amb el servidor", "pad.modals.disconnected.explanation": "S'ha perdut la connexió amb el servidor",
"pad.modals.disconnected.cause": "El servidor sembla que no està disponible. Notifiqueu a l'administrador del servei si continua passant.", "pad.modals.disconnected.cause": "El servidor sembla que no està disponible. Notifiqueu a l'administrador del servei si continua passant.",
@ -94,6 +100,7 @@
"pad.chat.loadmessages": "Carrega més missatges", "pad.chat.loadmessages": "Carrega més missatges",
"pad.chat.stick.title": "Ancora el xat a la pantalla", "pad.chat.stick.title": "Ancora el xat a la pantalla",
"pad.chat.writeMessage.placeholder": "Escriviu el vostre missatge a continuació", "pad.chat.writeMessage.placeholder": "Escriviu el vostre missatge a continuació",
"timeslider.followContents": "Fer seguiment de les actualitzacions de contingut del bloc",
"timeslider.pageTitle": "Línia temporal — {{appTitle}}", "timeslider.pageTitle": "Línia temporal — {{appTitle}}",
"timeslider.toolbar.returnbutton": "Torna al pad", "timeslider.toolbar.returnbutton": "Torna al pad",
"timeslider.toolbar.authors": "Autors:", "timeslider.toolbar.authors": "Autors:",
@ -126,7 +133,7 @@
"pad.userlist.guest": "Convidat", "pad.userlist.guest": "Convidat",
"pad.userlist.deny": "Refusa", "pad.userlist.deny": "Refusa",
"pad.userlist.approve": "Aprova", "pad.userlist.approve": "Aprova",
"pad.editbar.clearcolors": "Voleu netejar els colors d'autor del document sencer?", "pad.editbar.clearcolors": "Netejar els colors d'autor del document sencer?",
"pad.impexp.importbutton": "Importa ara", "pad.impexp.importbutton": "Importa ara",
"pad.impexp.importing": "Important...", "pad.impexp.importing": "Important...",
"pad.impexp.confirmimport": "En importar un fitxer se sobreescriurà el text actual del pad. Esteu segur que voleu continuar?", "pad.impexp.confirmimport": "En importar un fitxer se sobreescriurà el text actual del pad. Esteu segur que voleu continuar?",
@ -135,5 +142,7 @@
"pad.impexp.uploadFailed": "Ha fallat la càrrega. Torneu-ho a provar", "pad.impexp.uploadFailed": "Ha fallat la càrrega. Torneu-ho a provar",
"pad.impexp.importfailed": "Ha fallat la importació", "pad.impexp.importfailed": "Ha fallat la importació",
"pad.impexp.copypaste": "Si us plau, copieu i enganxeu", "pad.impexp.copypaste": "Si us plau, copieu i enganxeu",
"pad.impexp.exportdisabled": "Està inhabilitada l'exportació com a {{type}}. Contacteu amb el vostre administrador de sistemes per a més informació." "pad.impexp.exportdisabled": "Està inhabilitada l'exportació com a {{type}}. Contacteu amb el vostre administrador de sistemes per a més informació.",
"pad.impexp.maxFileSize": "Arxiu massa gran. Poseu-vos en contacte amb l'administrador del vostre lloc per augmentar la mida màxima dels fitxers importats",
"pad.impexp.permission": "La importació està desactivada perquè mai heu contribuït a aquest bloc. Si us plau, contribuïu almenys un cop abans d'importar"
} }

View file

@ -44,6 +44,8 @@
"pad.settings.fontType": "Skrifttype:", "pad.settings.fontType": "Skrifttype:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Sprog:", "pad.settings.language": "Sprog:",
"pad.settings.about": "Om",
"pad.settings.poweredBy": "Drevet af",
"pad.importExport.import_export": "Import/Eksport", "pad.importExport.import_export": "Import/Eksport",
"pad.importExport.import": "Uploade en tekstfil eller dokument", "pad.importExport.import": "Uploade en tekstfil eller dokument",
"pad.importExport.importSuccessful": "Vellykket!", "pad.importExport.importSuccessful": "Vellykket!",

View file

@ -2,17 +2,20 @@
"@metadata": { "@metadata": {
"authors": [ "authors": [
"Bjarncraft", "Bjarncraft",
"Dom",
"Metalhead64", "Metalhead64",
"Mklehr", "Mklehr",
"Nipsky", "Nipsky",
"Predatorix", "Predatorix",
"Sebastian Wallroth", "Sebastian Wallroth",
"Thargon", "Thargon",
"Tim.krieger",
"Wikinaut" "Wikinaut"
] ]
}, },
"index.newPad": "Neues Pad", "index.newPad": "Neues Pad",
"index.createOpenPad": "oder ein Pad mit folgendem Namen erstellen/öffnen:", "index.createOpenPad": "oder ein Pad mit folgendem Namen erstellen/öffnen:",
"index.openPad": "Öffne ein vorhandenes Pad mit folgendem Namen:",
"pad.toolbar.bold.title": "Fett (Strg-B)", "pad.toolbar.bold.title": "Fett (Strg-B)",
"pad.toolbar.italic.title": "Kursiv (Strg-I)", "pad.toolbar.italic.title": "Kursiv (Strg-I)",
"pad.toolbar.underline.title": "Unterstrichen (Strg-U)", "pad.toolbar.underline.title": "Unterstrichen (Strg-U)",
@ -33,10 +36,10 @@
"pad.colorpicker.save": "Speichern", "pad.colorpicker.save": "Speichern",
"pad.colorpicker.cancel": "Abbrechen", "pad.colorpicker.cancel": "Abbrechen",
"pad.loading": "Lade …", "pad.loading": "Lade …",
"pad.noCookie": "Das Cookie konnte nicht gefunden werden. Bitte erlaube Cookies in deinem Browser!", "pad.noCookie": "Das Cookie konnte nicht gefunden werden. Bitte erlaube Cookies in deinem Browser! Deine Sitzung und Einstellungen werden zwischen den Besuchen nicht gespeichert. Dies kann darauf zurückzuführen sein, dass Etherpad in einigen Browsern in einem iFrame enthalten ist. Bitte stelle sicher, dass sich Etherpad auf der gleichen Subdomain/Domain wie der übergeordnete iFrame befindet.",
"pad.passwordRequired": "Sie benötigen ein Kennwort, um auf dieses Pad zuzugreifen", "pad.passwordRequired": "Du benötigst ein Kennwort, um auf dieses Pad zuzugreifen",
"pad.permissionDenied": "Sie haben keine Berechtigung, um auf dieses Pad zuzugreifen", "pad.permissionDenied": "Du hast keine Berechtigung, um auf dieses Pad zuzugreifen",
"pad.wrongPassword": "Ihr eingegebenes Kennwort war falsch", "pad.wrongPassword": "Dein eingegebenes Kennwort war falsch",
"pad.settings.padSettings": "Pad-Einstellungen", "pad.settings.padSettings": "Pad-Einstellungen",
"pad.settings.myView": "Eigene Ansicht", "pad.settings.myView": "Eigene Ansicht",
"pad.settings.stickychat": "Unterhaltung immer anzeigen", "pad.settings.stickychat": "Unterhaltung immer anzeigen",
@ -47,8 +50,10 @@
"pad.settings.fontType": "Schriftart:", "pad.settings.fontType": "Schriftart:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Sprache:", "pad.settings.language": "Sprache:",
"pad.settings.about": "Über",
"pad.settings.poweredBy": "Powered by $1",
"pad.importExport.import_export": "Import/Export", "pad.importExport.import_export": "Import/Export",
"pad.importExport.import": "Text-Datei oder Dokument hochladen", "pad.importExport.import": "Textdatei oder Dokument hochladen",
"pad.importExport.importSuccessful": "Erfolgreich!", "pad.importExport.importSuccessful": "Erfolgreich!",
"pad.importExport.export": "Aktuelles Pad exportieren als:", "pad.importExport.export": "Aktuelles Pad exportieren als:",
"pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exportetherpad": "Etherpad",
@ -57,7 +62,7 @@
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)", "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-with-AbiWord\">installieren Sie bitte AbiWord oder LibreOffice</a>.", "pad.importExport.abiword.innerHTML": "Du kannst 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\">muss AbiWord oder LibreOffice auf dem Server installiert werden</a>.",
"pad.modals.connected": "Verbunden.", "pad.modals.connected": "Verbunden.",
"pad.modals.reconnecting": "Wiederherstellen der Verbindung …", "pad.modals.reconnecting": "Wiederherstellen der Verbindung …",
"pad.modals.forcereconnect": "Erneutes Verbinden erzwingen", "pad.modals.forcereconnect": "Erneutes Verbinden erzwingen",
@ -65,25 +70,27 @@
"pad.modals.cancel": "Abbrechen", "pad.modals.cancel": "Abbrechen",
"pad.modals.userdup": "In einem anderen Fenster geöffnet", "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.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.", "pad.modals.userdup.advice": "Verbinde dich erneut, um stattdessen dieses Fenster zu verwenden.",
"pad.modals.unauth": "Nicht berechtigt", "pad.modals.unauth": "Nicht berechtigt",
"pad.modals.unauth.explanation": "Ihre Zugriffsberechtigung für dieses Pad hat sich zwischenzeitlich geändert. Versuchen Sie sich erneut zu verbinden.", "pad.modals.unauth.explanation": "Deine Zugriffsberechtigung für dieses Pad hat sich zwischenzeitlich geändert. Versuche dich erneut zu verbinden.",
"pad.modals.looping.explanation": "Es gibt Verbindungsprobleme mit dem Server.", "pad.modals.looping.explanation": "Es gibt Verbindungsprobleme mit dem Server.",
"pad.modals.looping.cause": "Möglicherweise sind Sie durch eine inkompatible Firewall oder über einen inkompatiblen Proxy mit dem Server verbunden.", "pad.modals.looping.cause": "Möglicherweise bist du durch eine inkompatible Firewall oder über einen inkompatiblen Proxy mit dem Server verbunden.",
"pad.modals.initsocketfail": "Der Server ist nicht erreichbar.", "pad.modals.initsocketfail": "Der Server ist nicht erreichbar.",
"pad.modals.initsocketfail.explanation": "Es konnte keine Verbindung zum Server hergestellt werden.", "pad.modals.initsocketfail.explanation": "Es konnte keine Verbindung zum Server hergestellt werden.",
"pad.modals.initsocketfail.cause": "Dies könnte an Ihrem Browser oder Ihrer Internet-Verbindung liegen.", "pad.modals.initsocketfail.cause": "Dies könnte an deinem Browser oder deiner Internet-Verbindung liegen.",
"pad.modals.slowcommit.explanation": "Der Server antwortet nicht.", "pad.modals.slowcommit.explanation": "Der Server antwortet nicht.",
"pad.modals.slowcommit.cause": "Dies könnte ein Netzwerkverbindungsproblem sein oder eine momentane Überlastung des Servers.", "pad.modals.slowcommit.cause": "Dies könnte ein Netzwerkverbindungsproblem sein oder eine momentane Überlastung des Servers.",
"pad.modals.badChangeset.explanation": "Eine von Ihnen gemachte Änderung wurde vom Server als ungültig eingestuft.", "pad.modals.badChangeset.explanation": "Eine von dir gemachte Änderung wurde vom Server als ungültig eingestuft.",
"pad.modals.badChangeset.cause": "Dies könnte aufgrund einer falschen Serverkonfiguration oder eines anderen unerwarteten Verhaltens passiert sein. Bitte kontaktiere den Diensteadministrator, falls du glaubst, dass es sich um einen Fehler handelt. Versuche dich erneut zu verbinden, um mit dem Bearbeiten fortzufahren.", "pad.modals.badChangeset.cause": "Dies könnte aufgrund einer falschen Serverkonfiguration oder eines anderen unerwarteten Verhaltens passiert sein. Bitte kontaktiere den Diensteadministrator, falls du glaubst, dass es sich um einen Fehler handelt. Versuche dich erneut zu verbinden, um mit dem Bearbeiten fortzufahren.",
"pad.modals.corruptPad.explanation": "Das Pad, auf das Sie versuchen zuzugreifen, ist beschädigt.", "pad.modals.corruptPad.explanation": "Das Pad, auf das du versuchst zuzugreifen, ist beschädigt.",
"pad.modals.corruptPad.cause": "Dies könnte an einer falschen Serverkonfiguration oder eines anderen unerwarteten Verhaltens liegen. Bitte kontaktieren Sie den Administrator dieses Dienstes.", "pad.modals.corruptPad.cause": "Dies könnte an einer falschen Serverkonfiguration oder einem anderen unerwarteten Verhalten liegen. Bitte kontaktiere den Administrator dieses Dienstes.",
"pad.modals.deleted": "Gelöscht.", "pad.modals.deleted": "Gelöscht.",
"pad.modals.deleted.explanation": "Dieses Pad wurde entfernt.", "pad.modals.deleted.explanation": "Dieses Pad wurde entfernt.",
"pad.modals.rateLimited": "Begrenzte Rate.",
"pad.modals.rateLimited.explanation": "Sie haben zu viele Nachrichten an dieses Pad gesendet, so dass die Verbindung unterbrochen wurde.",
"pad.modals.disconnected": "Ihre Verbindung wurde getrennt.", "pad.modals.disconnected": "Ihre Verbindung wurde getrennt.",
"pad.modals.disconnected.explanation": "Die Verbindung zum Server wurde unterbrochen.", "pad.modals.disconnected.explanation": "Die Verbindung zum Server wurde unterbrochen.",
"pad.modals.disconnected.cause": "Möglicherweise ist der Server nicht erreichbar. Bitte benachrichtigen Sie den Dienstadministrator, falls dies weiterhin passiert.", "pad.modals.disconnected.cause": "Möglicherweise ist der Server nicht erreichbar. Bitte benachrichtige den Dienstadministrator, falls dies weiterhin passiert.",
"pad.share": "Dieses Pad teilen", "pad.share": "Dieses Pad teilen",
"pad.share.readonly": "Eingeschränkter Nur-Lese-Zugriff", "pad.share.readonly": "Eingeschränkter Nur-Lese-Zugriff",
"pad.share.link": "Verknüpfung", "pad.share.link": "Verknüpfung",
@ -93,6 +100,7 @@
"pad.chat.loadmessages": "Weitere Nachrichten laden", "pad.chat.loadmessages": "Weitere Nachrichten laden",
"pad.chat.stick.title": "Chat an den Bildschirm anheften", "pad.chat.stick.title": "Chat an den Bildschirm anheften",
"pad.chat.writeMessage.placeholder": "Schreibe hier deine Nachricht", "pad.chat.writeMessage.placeholder": "Schreibe hier deine Nachricht",
"timeslider.followContents": "Aktualisierungen des Pad-Inhalts verfolgen",
"timeslider.pageTitle": "{{appTitle}} Bearbeitungsverlauf", "timeslider.pageTitle": "{{appTitle}} Bearbeitungsverlauf",
"timeslider.toolbar.returnbutton": "Zurück zum Pad", "timeslider.toolbar.returnbutton": "Zurück zum Pad",
"timeslider.toolbar.authors": "Autoren:", "timeslider.toolbar.authors": "Autoren:",
@ -102,8 +110,8 @@
"timeslider.version": "Version {{version}}", "timeslider.version": "Version {{version}}",
"timeslider.saved": "Gespeichert am {{day}}. {{month}} {{year}}", "timeslider.saved": "Gespeichert am {{day}}. {{month}} {{year}}",
"timeslider.playPause": "Padbearbeitung abspielen/pausieren", "timeslider.playPause": "Padbearbeitung abspielen/pausieren",
"timeslider.backRevision": "Eine Version in diesem Pad zurück gehen", "timeslider.backRevision": "Eine Version in diesem Pad zurückgehen",
"timeslider.forwardRevision": "Eine Version in diesem Pad vorwärts gehen", "timeslider.forwardRevision": "Eine Version in diesem Pad vorwärtsgehen",
"timeslider.dateformat": "{{day}}.{{month}}.{{year}} {{hours}}:{{minutes}}:{{seconds}}", "timeslider.dateformat": "{{day}}.{{month}}.{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Januar", "timeslider.month.january": "Januar",
"timeslider.month.february": "Februar", "timeslider.month.february": "Februar",
@ -119,22 +127,22 @@
"timeslider.month.december": "Dezember", "timeslider.month.december": "Dezember",
"timeslider.unnamedauthors": "{{num}} {[plural(num) one: unbenannter Autor, other: unbenannte Autoren ]}", "timeslider.unnamedauthors": "{{num}} {[plural(num) one: unbenannter Autor, other: unbenannte Autoren ]}",
"pad.savedrevs.marked": "Diese Version wurde jetzt als gespeicherte Version gekennzeichnet", "pad.savedrevs.marked": "Diese Version wurde jetzt als gespeicherte Version gekennzeichnet",
"pad.savedrevs.timeslider": "Du kannst gespeicherte Versionen durch den Aufruf des Bearbeitungsverlaufes ansehen", "pad.savedrevs.timeslider": "Du kannst gespeicherte Versionen durch den Aufruf des Bearbeitungsverlaufes ansehen.",
"pad.userlist.entername": "Geben Sie Ihren Namen ein", "pad.userlist.entername": "Dein Name?",
"pad.userlist.unnamed": "unbenannt", "pad.userlist.unnamed": "unbenannt",
"pad.userlist.guest": "Gast", "pad.userlist.guest": "Gast",
"pad.userlist.deny": "Verweigern", "pad.userlist.deny": "Verweigern",
"pad.userlist.approve": "Genehmigen", "pad.userlist.approve": "Genehmigen",
"pad.editbar.clearcolors": "Autorenfarben im gesamten Dokument zurücksetzen?", "pad.editbar.clearcolors": "Autorenfarben im gesamten Dokument zurücksetzen? Dies kann nicht rückgängig gemacht werden",
"pad.impexp.importbutton": "Jetzt importieren", "pad.impexp.importbutton": "Jetzt importieren",
"pad.impexp.importing": "Importiere …", "pad.impexp.importing": "Importiere …",
"pad.impexp.confirmimport": "Das Importieren einer Datei überschreibt den aktuellen Text des Pads. Wollen Sie wirklich fortfahren?", "pad.impexp.confirmimport": "Das Importieren einer Datei überschreibt den aktuellen Text des Pads. Willst du wirklich fortfahren?",
"pad.impexp.convertFailed": "Diese Datei konnte nicht importiert werden. Bitte verwenden Sie ein anderes Dokumentformat oder übertragen Sie den Text manuell.", "pad.impexp.convertFailed": "Diese Datei konnte nicht importiert werden. Bitte verwende ein anderes Dokumentformat oder übertrage den Text manuell.",
"pad.impexp.padHasData": "Diese Datei konnte nicht importiert werden, da dieses Pad bereits Änderungen enthält. Bitte importieren Sie die Datei in ein neues Pad.", "pad.impexp.padHasData": "Diese Datei konnte nicht importiert werden, da dieses Pad bereits Änderungen enthält. Bitte importiere die Datei in ein neues Pad.",
"pad.impexp.uploadFailed": "Das Hochladen ist fehlgeschlagen. Bitte versuchen Sie es erneut.", "pad.impexp.uploadFailed": "Das Hochladen ist fehlgeschlagen. Bitte versuche es erneut.",
"pad.impexp.importfailed": "Import fehlgeschlagen", "pad.impexp.importfailed": "Import fehlgeschlagen",
"pad.impexp.copypaste": "Bitte kopieren und einfügen", "pad.impexp.copypaste": "Bitte kopieren und einfügen",
"pad.impexp.exportdisabled": "Der Export im {{type}}-Format ist deaktiviert. Für Einzelheiten kontaktieren Sie bitte Ihren Systemadministrator.", "pad.impexp.exportdisabled": "Der Export im {{type}}-Format ist deaktiviert. Für Einzelheiten kontaktiere bitte deinen Systemadministrator.",
"pad.impexp.maxFileSize": "Datei zu groß.Kontaktiere deinen Administrator um das datei Limit für Imports zu erhöhen.", "pad.impexp.maxFileSize": "Die Datei ist zu groß. Kontaktiere bitte deinen Administrator, um das Limit für den Dateiimport zu erhöhen.",
"pad.impexp.permission": "Importieren ist deaktiviert weil du nichts zu diesem Pad beigeteagen hast.Bitte trage etwas bei bevor du importierst." "pad.impexp.permission": "Die Importfunktion ist deaktiviert, da du noch nichts zu diesem Pad beigetragen hast. Bitte trage etwas zu diesem Pad bei, bevor du importierst."
} }

View file

@ -12,6 +12,7 @@
}, },
"index.newPad": "Bloknoto newe", "index.newPad": "Bloknoto newe",
"index.createOpenPad": "ya zi be nê nameyi ra yew bloknot vıraze/ake:", "index.createOpenPad": "ya zi be nê nameyi ra yew bloknot vıraze/ake:",
"index.openPad": "yew Padê biyayeyi be nê nameyi ra ake:",
"pad.toolbar.bold.title": "Qalınd (Ctrl-B)", "pad.toolbar.bold.title": "Qalınd (Ctrl-B)",
"pad.toolbar.italic.title": "Namıte (Ctrl-I)", "pad.toolbar.italic.title": "Namıte (Ctrl-I)",
"pad.toolbar.underline.title": "Bınxetın (Ctrl-U)", "pad.toolbar.underline.title": "Bınxetın (Ctrl-U)",
@ -32,7 +33,7 @@
"pad.colorpicker.save": "Qeyd ke", "pad.colorpicker.save": "Qeyd ke",
"pad.colorpicker.cancel": "Bıtexelne", "pad.colorpicker.cancel": "Bıtexelne",
"pad.loading": "Bar beno...", "pad.loading": "Bar beno...",
"pad.noCookie": "Çerez nêvibeya. Rovıter de çereza aktiv kerê", "pad.noCookie": "Çerez nêvineya. Rovıter de çereza aktiv kerê.Ronıştısê u eyarê şıma mabênê ziyareti qeyd nêbenê.Çıkı, Etherpad tay rovıteran de tewrê yew iFrame belka biyo. Kerem ke Etherpad corên iFrame ya wa eyni bınca/ca de zey pê bo.",
"pad.passwordRequired": "Ena bloknot resayışi rê parola icab krna", "pad.passwordRequired": "Ena bloknot resayışi rê parola icab krna",
"pad.permissionDenied": "Ena bloknot resayışi rê icazeta şıma çıni ya", "pad.permissionDenied": "Ena bloknot resayışi rê icazeta şıma çıni ya",
"pad.wrongPassword": "Parola şıma ğeleta", "pad.wrongPassword": "Parola şıma ğeleta",
@ -46,6 +47,8 @@
"pad.settings.fontType": "Babeta nuşti:", "pad.settings.fontType": "Babeta nuşti:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Zıwan:", "pad.settings.language": "Zıwan:",
"pad.settings.about": "Heqa",
"pad.settings.poweredBy": "Pheştidayoğ",
"pad.importExport.import_export": "Zerredayış/Teberdayış", "pad.importExport.import_export": "Zerredayış/Teberdayış",
"pad.importExport.import": "Dosya ya zi dokumanê meqaleyê de tesadufi bar ke", "pad.importExport.import": "Dosya ya zi dokumanê meqaleyê de tesadufi bar ke",
"pad.importExport.importSuccessful": "Mıwafaq biye", "pad.importExport.importSuccessful": "Mıwafaq biye",
@ -80,6 +83,8 @@
"pad.modals.corruptPad.cause": "Eno, xırab vıraziyena rovıteri yana nezanaye xırab yew faktori ra amrya meydan. Ena şıma çımdı xeta yena se idarekaran de sisteniya irtibat kewê", "pad.modals.corruptPad.cause": "Eno, xırab vıraziyena rovıteri yana nezanaye xırab yew faktori ra amrya meydan. Ena şıma çımdı xeta yena se idarekaran de sisteniya irtibat kewê",
"pad.modals.deleted": "Esteriya.", "pad.modals.deleted": "Esteriya.",
"pad.modals.deleted.explanation": "Ena ped wedariye", "pad.modals.deleted.explanation": "Ena ped wedariye",
"pad.modals.rateLimited": "Nısbeto kemeyeyın",
"pad.modals.rateLimited.explanation": "Na pad re ßıma vêşi mesac rışto, coki ra irtibat bıriyayo.",
"pad.modals.disconnected": "İrtibata şıma reyê", "pad.modals.disconnected": "İrtibata şıma reyê",
"pad.modals.disconnected.explanation": "Rovıteri ya irtibata şıma reyyê", "pad.modals.disconnected.explanation": "Rovıteri ya irtibata şıma reyyê",
"pad.modals.disconnected.cause": "Qay rovıtero nêkarên o. Ena xerpey deqam kena se idarekaranê sistemiya irtibat kewê", "pad.modals.disconnected.cause": "Qay rovıtero nêkarên o. Ena xerpey deqam kena se idarekaranê sistemiya irtibat kewê",
@ -92,6 +97,7 @@
"pad.chat.loadmessages": "Dehana zaf mesaci bar keri", "pad.chat.loadmessages": "Dehana zaf mesaci bar keri",
"pad.chat.stick.title": "Mobet ekran de bıvındarne", "pad.chat.stick.title": "Mobet ekran de bıvındarne",
"pad.chat.writeMessage.placeholder": "Mesacê xo tiya bınusne", "pad.chat.writeMessage.placeholder": "Mesacê xo tiya bınusne",
"timeslider.followContents": "Rocaney zerrekê padi taqib bıkerê",
"timeslider.pageTitle": ızagê zemani {{appTitle}}", "timeslider.pageTitle": ızagê zemani {{appTitle}}",
"timeslider.toolbar.returnbutton": "Peyser şo ped", "timeslider.toolbar.returnbutton": "Peyser şo ped",
"timeslider.toolbar.authors": "Nuştoği:", "timeslider.toolbar.authors": "Nuştoği:",

View file

@ -5,11 +5,13 @@
"Geraki", "Geraki",
"Glavkos", "Glavkos",
"Monopatis", "Monopatis",
"Norhorn",
"Protnet" "Protnet"
] ]
}, },
"index.newPad": "Νέο Pad", "index.newPad": "Νέο Pad",
"index.createOpenPad": "ή δημιουργία/άνοιγμα ενός Pad με όνομα:", "index.createOpenPad": "ή δημιουργία/άνοιγμα ενός Pad με όνομα:",
"index.openPad": "άνοιγμα υπάρχων Pad με όνομα:",
"pad.toolbar.bold.title": "Έντονη (Ctrl-B)", "pad.toolbar.bold.title": "Έντονη (Ctrl-B)",
"pad.toolbar.italic.title": "Πλάγια (Ctrl-I)", "pad.toolbar.italic.title": "Πλάγια (Ctrl-I)",
"pad.toolbar.underline.title": "Υπογράμμιση (Ctrl-U)", "pad.toolbar.underline.title": "Υπογράμμιση (Ctrl-U)",
@ -30,10 +32,10 @@
"pad.colorpicker.save": "Αποθήκευση", "pad.colorpicker.save": "Αποθήκευση",
"pad.colorpicker.cancel": "Άκυρο", "pad.colorpicker.cancel": "Άκυρο",
"pad.loading": "Φόρτωση...", "pad.loading": "Φόρτωση...",
"pad.noCookie": "Το cookie δεν βρέθηκε. Παρακαλώ επιτρέψτε τα cookies στον περιηγητή σας!", "pad.noCookie": "Το cookie δεν βρέθηκε. Παρακαλώ επιτρέψτε τα cookies στον περιηγητή σας! Η περίοδος σύνδεσης και οι ρυθμίσεις σας δεν θα αποθηκευτούν μεταξύ των επισκέψεων. Αυτό μπορεί να οφείλεται στο ότι το Etherpad περιλαμβάνεται σε ένα iFrame σε ορισμένα προγράμματα περιήγησης. Βεβαιωθείτε ότι το Etherpad βρίσκεται στον ίδιο υποτομέα/τομέα με το γονικό iFrame",
"pad.passwordRequired": "Χρειάζεστε κωδικό πρόσβασης για πρόσβαση σε αυτό το pad", "pad.passwordRequired": "Χρειάζεστε συνθηματικό για πρόσβαση σε αυτό το pad",
"pad.permissionDenied": "Δεν έχετε δικαίωμα πρόσβασης σε αυτό το pad", "pad.permissionDenied": "Δεν έχετε δικαίωμα πρόσβασης σε αυτό το pad",
"pad.wrongPassword": "Ο κωδικός σας ήταν λανθασμένος", "pad.wrongPassword": "Το συνθηματικό σας ήταν λανθασμένο",
"pad.settings.padSettings": "Ρυθμίσεις Pad", "pad.settings.padSettings": "Ρυθμίσεις Pad",
"pad.settings.myView": "Η προβολή μου", "pad.settings.myView": "Η προβολή μου",
"pad.settings.stickychat": "Να είναι πάντα ορατή η συνομιλία", "pad.settings.stickychat": "Να είναι πάντα ορατή η συνομιλία",
@ -44,8 +46,10 @@
"pad.settings.fontType": "Τύπος γραμματοσειράς:", "pad.settings.fontType": "Τύπος γραμματοσειράς:",
"pad.settings.fontType.normal": "Κανονική", "pad.settings.fontType.normal": "Κανονική",
"pad.settings.language": "Γλώσσα:", "pad.settings.language": "Γλώσσα:",
"pad.settings.about": "Σχετικά",
"pad.settings.poweredBy": "Υποστηρίζεται από",
"pad.importExport.import_export": "Εισαγωγή/Εξαγωγή", "pad.importExport.import_export": "Εισαγωγή/Εξαγωγή",
"pad.importExport.import": "Αποστολή οποιουδήποτε αρχείου κειμένου ή εγγράφου", "pad.importExport.import": "Μεταφόρτωση οποιουδήποτε αρχείου κειμένου ή εγγράφου",
"pad.importExport.importSuccessful": "Επιτυχής!", "pad.importExport.importSuccessful": "Επιτυχής!",
"pad.importExport.export": "Εξαγωγή τρέχοντος pad ως:", "pad.importExport.export": "Εξαγωγή τρέχοντος pad ως:",
"pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exportetherpad": "Etherpad",
@ -53,12 +57,12 @@
"pad.importExport.exportplain": "Απλό κείμενο", "pad.importExport.exportplain": "Απλό κείμενο",
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Μορφή Open Document)", "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 ή το LibreOffice</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 ή το LibreOffice</a>.",
"pad.modals.connected": "Συνδεμένοι.", "pad.modals.connected": "Συνδεμένοι.",
"pad.modals.reconnecting": "Επανασύνδεση στο pad σας...", "pad.modals.reconnecting": "Επανασύνδεση στο pad σας...",
"pad.modals.forcereconnect": "Επιβολή επανασύνδεσης", "pad.modals.forcereconnect": "Επιβολή επανασύνδεσης",
"pad.modals.reconnecttimer": "Επαναπροσπάθεια σε", "pad.modals.reconnecttimer": "Προσπάθεια επανασύνδεσης σε",
"pad.modals.cancel": "Ακύρωση", "pad.modals.cancel": "Ακύρωση",
"pad.modals.userdup": "Ανοιγμένο σε άλλο παράθυρο", "pad.modals.userdup": "Ανοιγμένο σε άλλο παράθυρο",
"pad.modals.userdup.explanation": "Αυτό το pad φαίνεται να είναι ανοιχτό σε περισσότερα από ένα παράθυρο του προγράμματος περιήγησης σε αυτόν τον υπολογιστή.", "pad.modals.userdup.explanation": "Αυτό το pad φαίνεται να είναι ανοιχτό σε περισσότερα από ένα παράθυρο του προγράμματος περιήγησης σε αυτόν τον υπολογιστή.",
@ -123,13 +127,15 @@
"pad.userlist.deny": "Άρνηση", "pad.userlist.deny": "Άρνηση",
"pad.userlist.approve": "Έγκριση", "pad.userlist.approve": "Έγκριση",
"pad.editbar.clearcolors": "Να γίνει εκκαθάριση χρωμάτων σύνταξης σε ολόκληρο το έγγραφο; Αυτό δεν μπορεί να αναιρεθεί", "pad.editbar.clearcolors": "Να γίνει εκκαθάριση χρωμάτων σύνταξης σε ολόκληρο το έγγραφο; Αυτό δεν μπορεί να αναιρεθεί",
"pad.impexp.importbutton": "Εισαγωγή Τώρα", "pad.impexp.importbutton": "Εισαγωγή τώρα",
"pad.impexp.importing": "Εισάγεται...", "pad.impexp.importing": "Εισάγεται...",
"pad.impexp.confirmimport": "Η εισαγωγή ενός αρχείου θα αντικαταστήσει το κείμενο του pad. Είστε βέβαιοι ότι θέλετε να συνεχίσετε;", "pad.impexp.confirmimport": "Η εισαγωγή ενός αρχείου θα αντικαταστήσει το κείμενο του pad. Είστε βέβαιοι ότι θέλετε να συνεχίσετε;",
"pad.impexp.convertFailed": "Δεν καταφέραμε να εισάγουμε αυτό το αρχείο. Παρακαλώ χρησιμοποιήστε διαφορετικό τύπο αρχείου ή αντιγράψτε και επικολλήστε χειροκίνητα", "pad.impexp.convertFailed": "Δεν καταφέραμε να εισάγουμε αυτό το αρχείο. Παρακαλώ χρησιμοποιήστε διαφορετικό τύπο αρχείου ή αντιγράψτε και επικολλήστε χειροκίνητα",
"pad.impexp.padHasData": "Δεν μπορέσαμε να εισάγουμε το αρχείο επειδή το Pad είχε ήδη αλλαγές. Παρακαλούμε εισαγάγετε το αρχείο σε νέο pad", "pad.impexp.padHasData": "Δεν μπορέσαμε να εισάγουμε το αρχείο επειδή το Pad είχε ήδη αλλαγές. Παρακαλούμε εισαγάγετε το αρχείο σε νέο pad",
"pad.impexp.uploadFailed": "Η αποστολή απέτυχε, παρακαλώ προσπαθήστε ξανά", "pad.impexp.uploadFailed": "Η μεταφόρτωση απέτυχε, παρακαλούμε προσπαθήστε ξανά",
"pad.impexp.importfailed": "Η εισαγωγή απέτυχε", "pad.impexp.importfailed": "Η εισαγωγή απέτυχε",
"pad.impexp.copypaste": "Παρακαλώ αντιγράψτε και επικολλήστε", "pad.impexp.copypaste": "Παρακαλώ αντιγράψτε και επικολλήστε",
"pad.impexp.exportdisabled": "Η εξαγωγή σε μορφή {{type}} έχει απενεργοποιηθεί. Επικοινωνήστε με τον διαχειριστή του συστήματός σας για λεπτομέρειες." "pad.impexp.exportdisabled": "Η εξαγωγή σε μορφή {{type}} έχει απενεργοποιηθεί. Επικοινωνήστε με τον διαχειριστή του συστήματός σας για λεπτομέρειες.",
"pad.impexp.maxFileSize": "Πολύ μεγάλο αρχείο. Επικοινωνήστε με τον διαχειριστή για να αυξήσετε το επιτρεπόμενο μέγεθος αρχείου",
"pad.impexp.permission": "Η εισαγωγή είναι απενεργοποιημένη επειδή δεν συνεισφέρατε ποτέ σε αυτό το pad. Συνεισφέρετε τουλάχιστον μία φορά πριν από την εισαγωγή"
} }

View file

@ -2,6 +2,7 @@
"@metadata": { "@metadata": {
"authors": [ "authors": [
"Andibing", "Andibing",
"Bjh21",
"Cblair91", "Cblair91",
"Chase me ladies, I'm the Cavalry", "Chase me ladies, I'm the Cavalry",
"HairyFotr", "HairyFotr",
@ -30,7 +31,7 @@
"pad.colorpicker.save": "Save", "pad.colorpicker.save": "Save",
"pad.colorpicker.cancel": "Cancel", "pad.colorpicker.cancel": "Cancel",
"pad.loading": "Loading...", "pad.loading": "Loading...",
"pad.noCookie": "Cookie could not be found. Please allow cookies in your browser!", "pad.noCookie": "Cookie could not be found. Please allow cookies in your browser! Your session and settings will not be saved between visits. This may be due to Etherpad being included in an iFrame in some Browsers. Please ensure Etherpad is on the same subdomain/domain as the parent iFrame",
"pad.passwordRequired": "You need a password to access this pad", "pad.passwordRequired": "You need a password to access this pad",
"pad.permissionDenied": "You do not have permission to access this pad", "pad.permissionDenied": "You do not have permission to access this pad",
"pad.wrongPassword": "Your password was wrong", "pad.wrongPassword": "Your password was wrong",
@ -54,7 +55,7 @@
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)", "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-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 or LibreOffice</a>.",
"pad.modals.connected": "Connected.", "pad.modals.connected": "Connected.",
"pad.modals.reconnecting": "Reconnecting to your pad..", "pad.modals.reconnecting": "Reconnecting to your pad..",
"pad.modals.forcereconnect": "Force reconnect", "pad.modals.forcereconnect": "Force reconnect",
@ -122,7 +123,7 @@
"pad.userlist.guest": "Guest", "pad.userlist.guest": "Guest",
"pad.userlist.deny": "Deny", "pad.userlist.deny": "Deny",
"pad.userlist.approve": "Approve", "pad.userlist.approve": "Approve",
"pad.editbar.clearcolors": "Clear authorship colours on entire document?", "pad.editbar.clearcolors": "Clear authorship colours on entire document? This cannot be undone",
"pad.impexp.importbutton": "Import Now", "pad.impexp.importbutton": "Import Now",
"pad.impexp.importing": "Importing...", "pad.impexp.importing": "Importing...",
"pad.impexp.confirmimport": "Importing a file will overwrite the current text of the pad. Are you sure you want to proceed?", "pad.impexp.confirmimport": "Importing a file will overwrite the current text of the pad. Are you sure you want to proceed?",

View file

@ -1,6 +1,7 @@
{ {
"index.newPad": "New Pad", "index.newPad": "New Pad",
"index.createOpenPad": "or create/open a Pad with the name:", "index.createOpenPad": "or create/open a Pad with the name:",
"index.openPad": "open an existing Pad with the name:",
"pad.toolbar.bold.title": "Bold (Ctrl+B)", "pad.toolbar.bold.title": "Bold (Ctrl+B)",
"pad.toolbar.italic.title": "Italic (Ctrl+I)", "pad.toolbar.italic.title": "Italic (Ctrl+I)",
@ -24,7 +25,7 @@
"pad.colorpicker.cancel": "Cancel", "pad.colorpicker.cancel": "Cancel",
"pad.loading": "Loading...", "pad.loading": "Loading...",
"pad.noCookie": "Cookie could not be found. Please allow cookies in your browser!", "pad.noCookie": "Cookie could not be found. Please allow cookies in your browser! Your session and settings will not be saved between visits. This may be due to Etherpad being included in an iFrame in some Browsers. Please ensure Etherpad is on the same subdomain/domain as the parent iFrame",
"pad.passwordRequired": "You need a password to access this pad", "pad.passwordRequired": "You need a password to access this pad",
"pad.permissionDenied": "You do not have permission to access this pad", "pad.permissionDenied": "You do not have permission to access this pad",
"pad.wrongPassword": "Your password was wrong", "pad.wrongPassword": "Your password was wrong",
@ -39,6 +40,8 @@
"pad.settings.fontType": "Font type:", "pad.settings.fontType": "Font type:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Language:", "pad.settings.language": "Language:",
"pad.settings.about": "About",
"pad.settings.poweredBy": "Powered by",
"pad.importExport.import_export": "Import/Export", "pad.importExport.import_export": "Import/Export",
"pad.importExport.import": "Upload any text file or document", "pad.importExport.import": "Upload any text file or document",
@ -84,6 +87,9 @@
"pad.modals.deleted": "Deleted.", "pad.modals.deleted": "Deleted.",
"pad.modals.deleted.explanation": "This pad has been removed.", "pad.modals.deleted.explanation": "This pad has been removed.",
"pad.modals.rateLimited": "Rate Limited.",
"pad.modals.rateLimited.explanation": "You sent too many messages to this pad so it disconnected you.",
"pad.modals.disconnected": "You have been disconnected.", "pad.modals.disconnected": "You have been disconnected.",
"pad.modals.disconnected.explanation": "The connection to the server was lost", "pad.modals.disconnected.explanation": "The connection to the server was lost",
"pad.modals.disconnected.cause": "The server may be unavailable. Please notify the service administrator if this continues to happen.", "pad.modals.disconnected.cause": "The server may be unavailable. Please notify the service administrator if this continues to happen.",
@ -98,6 +104,7 @@
"pad.chat.stick.title": "Stick chat to screen", "pad.chat.stick.title": "Stick chat to screen",
"pad.chat.writeMessage.placeholder": "Write your message here", "pad.chat.writeMessage.placeholder": "Write your message here",
"timeslider.followContents": "Follow pad content updates",
"timeslider.pageTitle": "{{appTitle}} Timeslider", "timeslider.pageTitle": "{{appTitle}} Timeslider",
"timeslider.toolbar.returnbutton": "Return to pad", "timeslider.toolbar.returnbutton": "Return to pad",
"timeslider.toolbar.authors": "Authors:", "timeslider.toolbar.authors": "Authors:",

View file

@ -54,6 +54,8 @@
"pad.settings.fontType": "Tipografía:", "pad.settings.fontType": "Tipografía:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Idioma:", "pad.settings.language": "Idioma:",
"pad.settings.about": "Acerca de",
"pad.settings.poweredBy": "Funciona con",
"pad.importExport.import_export": "Importar/Exportar", "pad.importExport.import_export": "Importar/Exportar",
"pad.importExport.import": "Subir cualquier texto o documento", "pad.importExport.import": "Subir cualquier texto o documento",
"pad.importExport.importSuccessful": "¡Éxito!", "pad.importExport.importSuccessful": "¡Éxito!",

View file

@ -53,6 +53,8 @@
"pad.settings.fontType": "Fonttityyppi:", "pad.settings.fontType": "Fonttityyppi:",
"pad.settings.fontType.normal": "normaali", "pad.settings.fontType.normal": "normaali",
"pad.settings.language": "Kieli:", "pad.settings.language": "Kieli:",
"pad.settings.about": "Tietoja",
"pad.settings.poweredBy": "Palvelun mahdollistaa",
"pad.importExport.import_export": "Tuonti/vienti", "pad.importExport.import_export": "Tuonti/vienti",
"pad.importExport.import": "Lähetä mikä tahansa tekstitiedosto tai asiakirja", "pad.importExport.import": "Lähetä mikä tahansa tekstitiedosto tai asiakirja",
"pad.importExport.importSuccessful": "Onnistui!", "pad.importExport.importSuccessful": "Onnistui!",
@ -63,7 +65,7 @@
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)", "pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Tuonti on tuettu vain HTML- ja raakatekstitiedostoista. Monipuoliset tuontiominaisuudet ovat käytettävissä <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">asentamalla AbiWord</a>.", "pad.importExport.abiword.innerHTML": "Tuonti on tuettu vain HTML- ja raakatekstitiedostoista. Monipuoliset tuontiominaisuudet ovat käytettävissä <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">asentamalla AbiWordin tai LibreOfficen</a>.",
"pad.modals.connected": "Yhdistetty.", "pad.modals.connected": "Yhdistetty.",
"pad.modals.reconnecting": "Muodostetaan yhteyttä muistioon uudelleen...", "pad.modals.reconnecting": "Muodostetaan yhteyttä muistioon uudelleen...",
"pad.modals.forcereconnect": "Pakota yhdistämään uudelleen", "pad.modals.forcereconnect": "Pakota yhdistämään uudelleen",
@ -131,7 +133,7 @@
"pad.userlist.guest": "Vieras", "pad.userlist.guest": "Vieras",
"pad.userlist.deny": "Estä", "pad.userlist.deny": "Estä",
"pad.userlist.approve": "Hyväksy", "pad.userlist.approve": "Hyväksy",
"pad.editbar.clearcolors": "Poistetaanko asiakirjasta tekijävärit?", "pad.editbar.clearcolors": "Poistetaanko asiakirjasta tekijävärit? Tätä ei voi perua",
"pad.impexp.importbutton": "Tuo nyt", "pad.impexp.importbutton": "Tuo nyt",
"pad.impexp.importing": "Tuodaan...", "pad.impexp.importing": "Tuodaan...",
"pad.impexp.confirmimport": "Tiedoston tuonti korvaa kaiken muistiossa olevan tekstin. Haluatko varmasti jatkaa?", "pad.impexp.confirmimport": "Tiedoston tuonti korvaa kaiken muistiossa olevan tekstin. Haluatko varmasti jatkaa?",

View file

@ -22,6 +22,7 @@
"Quenenni", "Quenenni",
"Rastus Vernon", "Rastus Vernon",
"Stephane Cottin", "Stephane Cottin",
"Thibaut120094",
"Tux-tn", "Tux-tn",
"Urhixidur", "Urhixidur",
"Verdy p", "Verdy p",
@ -30,6 +31,7 @@
}, },
"index.newPad": "Nouveau bloc-notes", "index.newPad": "Nouveau bloc-notes",
"index.createOpenPad": "ou créer/ouvrir un bloc-notes intitulé:", "index.createOpenPad": "ou créer/ouvrir un bloc-notes intitulé:",
"index.openPad": "ouvrir un Pad existant avec le nom :",
"pad.toolbar.bold.title": "Gras (Ctrl+B)", "pad.toolbar.bold.title": "Gras (Ctrl+B)",
"pad.toolbar.italic.title": "Italique (Ctrl+I)", "pad.toolbar.italic.title": "Italique (Ctrl+I)",
"pad.toolbar.underline.title": "Souligné (Ctrl+U)", "pad.toolbar.underline.title": "Souligné (Ctrl+U)",
@ -50,7 +52,7 @@
"pad.colorpicker.save": "Enregistrer", "pad.colorpicker.save": "Enregistrer",
"pad.colorpicker.cancel": "Annuler", "pad.colorpicker.cancel": "Annuler",
"pad.loading": "Chargement...", "pad.loading": "Chargement...",
"pad.noCookie": "Un cookie na pas pu être trouvé. Veuillez autoriser les fichiers témoins (ou cookies) dans votre navigateur!", "pad.noCookie": "Un cookie na pas pu être trouvé. Veuillez autoriser les fichiers témoins (ou cookies) dans votre navigateur ! Votre session et vos paramètres ne seront pas enregistrés entre les visites. Cela peut être dû au fait quEtehrpad est inclus dans un iFrame dans certains navigateurs. Veuillez vous assurer que Etherpad est dans le même sous-domaine/domaine que son iFrame parent",
"pad.passwordRequired": "Vous avez besoin d'un mot de passe pour accéder à ce bloc-note", "pad.passwordRequired": "Vous avez besoin d'un mot de passe pour accéder à ce bloc-note",
"pad.permissionDenied": "Vous nêtes pas autorisé à accéder à ce bloc-notes", "pad.permissionDenied": "Vous nêtes pas autorisé à accéder à ce bloc-notes",
"pad.wrongPassword": "Votre mot de passe est incorrect", "pad.wrongPassword": "Votre mot de passe est incorrect",
@ -64,6 +66,8 @@
"pad.settings.fontType": "Police:", "pad.settings.fontType": "Police:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Langue:", "pad.settings.language": "Langue:",
"pad.settings.about": "À propos",
"pad.settings.poweredBy": "Fourni par",
"pad.importExport.import_export": "Importer/Exporter", "pad.importExport.import_export": "Importer/Exporter",
"pad.importExport.import": "Charger un texte ou un document", "pad.importExport.import": "Charger un texte ou un document",
"pad.importExport.importSuccessful": "Réussi!", "pad.importExport.importSuccessful": "Réussi!",
@ -98,6 +102,8 @@
"pad.modals.corruptPad.cause": "Cela peut être dû à une mauvaise configuration du serveur ou à un autre comportement inattendu. Veuillez contacter ladministrateur du service.", "pad.modals.corruptPad.cause": "Cela peut être dû à une mauvaise configuration du serveur ou à un autre comportement inattendu. Veuillez contacter ladministrateur du service.",
"pad.modals.deleted": "Supprimé.", "pad.modals.deleted": "Supprimé.",
"pad.modals.deleted.explanation": "Ce bloc-notes a été supprimé.", "pad.modals.deleted.explanation": "Ce bloc-notes a été supprimé.",
"pad.modals.rateLimited": "Taux limité.",
"pad.modals.rateLimited.explanation": "Vous avez envoyé trop de messages à ce bloc, il vous a donc déconnecté.",
"pad.modals.disconnected": "Vous avez été déconnecté.", "pad.modals.disconnected": "Vous avez été déconnecté.",
"pad.modals.disconnected.explanation": "La connexion au serveur a échoué.", "pad.modals.disconnected.explanation": "La connexion au serveur a échoué.",
"pad.modals.disconnected.cause": "Il se peut que le serveur soit indisponible. Si le problème persiste, veuillez en informer ladministrateur du service.", "pad.modals.disconnected.cause": "Il se peut que le serveur soit indisponible. Si le problème persiste, veuillez en informer ladministrateur du service.",
@ -110,6 +116,7 @@
"pad.chat.loadmessages": "Charger davantage de messages", "pad.chat.loadmessages": "Charger davantage de messages",
"pad.chat.stick.title": "Ancrer la discussion sur lécran", "pad.chat.stick.title": "Ancrer la discussion sur lécran",
"pad.chat.writeMessage.placeholder": "Entrez votre message ici", "pad.chat.writeMessage.placeholder": "Entrez votre message ici",
"timeslider.followContents": "Suivre les mises à jour de contenu du bloc",
"timeslider.pageTitle": "Historique dynamique de {{appTitle}}", "timeslider.pageTitle": "Historique dynamique de {{appTitle}}",
"timeslider.toolbar.returnbutton": "Retourner au bloc-notes", "timeslider.toolbar.returnbutton": "Retourner au bloc-notes",
"timeslider.toolbar.authors": "Auteurs:", "timeslider.toolbar.authors": "Auteurs:",

View file

@ -3,12 +3,14 @@
"authors": [ "authors": [
"Amire80", "Amire80",
"Ofrahod", "Ofrahod",
"Steeve815",
"YaronSh", "YaronSh",
"תומר ט" "תומר ט"
] ]
}, },
"index.newPad": "פנקס חדש", "index.newPad": "פנקס חדש",
"index.createOpenPad": "ליצור או לפתוח פנקס בשם:", "index.createOpenPad": "ליצור או לפתוח פנקס בשם:",
"index.openPad": "פתיחת פנקס קיים עם השם:",
"pad.toolbar.bold.title": "בולט (Ctrl-B)", "pad.toolbar.bold.title": "בולט (Ctrl-B)",
"pad.toolbar.italic.title": "נטוי (Ctrl-I)", "pad.toolbar.italic.title": "נטוי (Ctrl-I)",
"pad.toolbar.underline.title": "קו תחתי (Ctrl-U)", "pad.toolbar.underline.title": "קו תחתי (Ctrl-U)",
@ -43,6 +45,7 @@
"pad.settings.fontType": "סוג גופן:", "pad.settings.fontType": "סוג גופן:",
"pad.settings.fontType.normal": "רגיל", "pad.settings.fontType.normal": "רגיל",
"pad.settings.language": "שפה:", "pad.settings.language": "שפה:",
"pad.settings.about": "על אודות",
"pad.importExport.import_export": "ייבוא/ייצוא", "pad.importExport.import_export": "ייבוא/ייצוא",
"pad.importExport.import": "העלאת כל קובץ טקסט או מסמך", "pad.importExport.import": "העלאת כל קובץ טקסט או מסמך",
"pad.importExport.importSuccessful": "זה עבד!", "pad.importExport.importSuccessful": "זה עבד!",

View file

@ -7,6 +7,7 @@
}, },
"index.newPad": "Novi blokić", "index.newPad": "Novi blokić",
"index.createOpenPad": "ili stvori/otvori blokić s imenom:", "index.createOpenPad": "ili stvori/otvori blokić s imenom:",
"index.openPad": "otvori postojeći blokić Etherpada s imenom:",
"pad.toolbar.bold.title": "Masno (Ctrl+B)", "pad.toolbar.bold.title": "Masno (Ctrl+B)",
"pad.toolbar.italic.title": "Ukošeno (Ctrl+I)", "pad.toolbar.italic.title": "Ukošeno (Ctrl+I)",
"pad.toolbar.underline.title": "Podcrtano (Ctrl+U)", "pad.toolbar.underline.title": "Podcrtano (Ctrl+U)",
@ -27,7 +28,7 @@
"pad.colorpicker.save": "Spremi", "pad.colorpicker.save": "Spremi",
"pad.colorpicker.cancel": "Otkaži", "pad.colorpicker.cancel": "Otkaži",
"pad.loading": "Učitavanje...", "pad.loading": "Učitavanje...",
"pad.noCookie": "Kolačić nije pronađen. Molimo Vas da uključite kolačiće u Vašem pregledniku!", "pad.noCookie": "Kolačić nije pronađen. Molimo Vas, omogućite kolačiće u Vašem pregledniku! Sesija i postavke neće biti sačuvane između Vaših posjećivanja. Razlog može biti uključenost Etherpada u iFrame u nekim preglednicima. Molimo Vas, osigurajte da je Etherpad na istoj poddomeni/domeni kao i ''roditeljski'' iFrame.",
"pad.passwordRequired": "Potrebna Vam je zaporka za pristup ovomu blokiću", "pad.passwordRequired": "Potrebna Vam je zaporka za pristup ovomu blokiću",
"pad.permissionDenied": "Nemate dopuštenje za pristup ovome blokiću", "pad.permissionDenied": "Nemate dopuštenje za pristup ovome blokiću",
"pad.wrongPassword": "Vaša zaporka nije valjana", "pad.wrongPassword": "Vaša zaporka nije valjana",
@ -39,7 +40,10 @@
"pad.settings.linenocheck": "Brojevi redaka", "pad.settings.linenocheck": "Brojevi redaka",
"pad.settings.rtlcheck": "Želite li prikaz sadržaja s desna na lijevo?", "pad.settings.rtlcheck": "Želite li prikaz sadržaja s desna na lijevo?",
"pad.settings.fontType": "Vrsta fonta:", "pad.settings.fontType": "Vrsta fonta:",
"pad.settings.fontType.normal": "Normalna",
"pad.settings.language": "Jezik:", "pad.settings.language": "Jezik:",
"pad.settings.about": "O projektu",
"pad.settings.poweredBy": "Proizvod Vam pruža",
"pad.importExport.import_export": "Uvoz/Izvoz", "pad.importExport.import_export": "Uvoz/Izvoz",
"pad.importExport.import": "Postavite bilo koju tekstualnu datoteku ili dokument", "pad.importExport.import": "Postavite bilo koju tekstualnu datoteku ili dokument",
"pad.importExport.importSuccessful": "Uspješno!", "pad.importExport.importSuccessful": "Uspješno!",
@ -50,7 +54,7 @@
"pad.importExport.exportword": "Datoteku programa Microsoft Word", "pad.importExport.exportword": "Datoteku programa Microsoft Word",
"pad.importExport.exportpdf": "Datoteku Acrobatova PDF formata", "pad.importExport.exportpdf": "Datoteku Acrobatova PDF formata",
"pad.importExport.exportopen": "Datoteku formata Open Document (ODF)", "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.importExport.abiword.innerHTML": "Možete uvoziti samo datoteke formata za obični tekst (bez oblikovanja) te datoteke u formatima HTML-a. 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 ili LibreOffice</a>.",
"pad.modals.connected": "Povezano.", "pad.modals.connected": "Povezano.",
"pad.modals.reconnecting": "Ponovo Vas povezujemo s Vašim blokićem...", "pad.modals.reconnecting": "Ponovo Vas povezujemo s Vašim blokićem...",
"pad.modals.forcereconnect": "Prisilno se ponovo poveži", "pad.modals.forcereconnect": "Prisilno se ponovo poveži",
@ -74,6 +78,8 @@
"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.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": "Pobrisano.",
"pad.modals.deleted.explanation": "Blokić je bio uklonjen.", "pad.modals.deleted.explanation": "Blokić je bio uklonjen.",
"pad.modals.rateLimited": "Brzina slanja poruka na blokić je ograničena.",
"pad.modals.rateLimited.explanation": "Poslali ste previše poruka na ovaj blokić, te ste stoga odspojeni.",
"pad.modals.disconnected": "Vaša je veza prekinuta.", "pad.modals.disconnected": "Vaša je veza prekinuta.",
"pad.modals.disconnected.explanation": "Veza s poslužiteljem je izgubljena.", "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.modals.disconnected.cause": "Moguće je da poslužitelj nije dostupan. Molimo Vas, obavijestite administratora usluge ukoliko se to nastavi događati.",
@ -86,6 +92,7 @@
"pad.chat.loadmessages": "Učitaj više poruka", "pad.chat.loadmessages": "Učitaj više poruka",
"pad.chat.stick.title": "Prilijepi razgovor na zaslon", "pad.chat.stick.title": "Prilijepi razgovor na zaslon",
"pad.chat.writeMessage.placeholder": "Napišite Vašu poruku ovdje", "pad.chat.writeMessage.placeholder": "Napišite Vašu poruku ovdje",
"timeslider.followContents": "Prati ažuriranja sadržaja blokića",
"timeslider.pageTitle": "{{appTitle}} Vremenska lenta", "timeslider.pageTitle": "{{appTitle}} Vremenska lenta",
"timeslider.toolbar.returnbutton": "Vrati se natrag na blokić", "timeslider.toolbar.returnbutton": "Vrati se natrag na blokić",
"timeslider.toolbar.authors": "Autori:", "timeslider.toolbar.authors": "Autori:",
@ -127,5 +134,7 @@
"pad.impexp.uploadFailed": "Postavljanje nije uspjelo. molimo Vas, pokušajte ponovo", "pad.impexp.uploadFailed": "Postavljanje nije uspjelo. molimo Vas, pokušajte ponovo",
"pad.impexp.importfailed": "Uvoz nije uspio", "pad.impexp.importfailed": "Uvoz nije uspio",
"pad.impexp.copypaste": "Molimo preslikajte/zalijepite", "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." "pad.impexp.exportdisabled": "Izvoz u formatu {{type}} nije omogućen. Molimo Vas, kontaktirajte Vašega administratora sustava za više pojedinosti.",
"pad.impexp.maxFileSize": "Datoteka je prevelika. Kontaktirajte administratora Vašega mrežnoga sjedišta kako biste zatražili povećanje dopuštene veličine datoteke za uvoz",
"pad.impexp.permission": "Uvoz je onemogućen jer niste doprinosili ovom blokiću Etherpada. Molimo Vas, doprinosite barem jednom prije radnje uvoza"
} }

View file

@ -7,18 +7,20 @@
"Dj", "Dj",
"Misibacsi", "Misibacsi",
"Notramo", "Notramo",
"Ovari",
"R-Joe", "R-Joe",
"Tgr" "Tgr"
] ]
}, },
"index.newPad": "Új notesz", "index.newPad": "Új jegyzetfüzet",
"index.createOpenPad": "vagy notesz létrehozása/megnyitása ezzel a névvel:", "index.createOpenPad": "vagy jegyzetfüzet létrehozása/megnyitása ezzel a névvel:",
"index.openPad": "nyisson meg egy meglévő jegyzetfüzetet névvel:",
"pad.toolbar.bold.title": "Félkövér (Ctrl+B)", "pad.toolbar.bold.title": "Félkövér (Ctrl+B)",
"pad.toolbar.italic.title": "Dőlt (Ctrl+I)", "pad.toolbar.italic.title": "Dőlt (Ctrl+I)",
"pad.toolbar.underline.title": "Aláhúzás (Ctrl+U)", "pad.toolbar.underline.title": "Aláhúzás (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Áthúzás (Ctrl+5)", "pad.toolbar.strikethrough.title": "Áthúzás (Ctrl+5)",
"pad.toolbar.ol.title": "Számozott lista (Ctrl+Shift+N)", "pad.toolbar.ol.title": "Rendezett lista (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Számozatlan lista (Ctrl+Shift+L)", "pad.toolbar.ul.title": "Rendezetlen lista (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Behúzás növelése (TAB)", "pad.toolbar.indent.title": "Behúzás növelése (TAB)",
"pad.toolbar.unindent.title": "Behúzás csökkentése (Shift+TAB)", "pad.toolbar.unindent.title": "Behúzás csökkentése (Shift+TAB)",
"pad.toolbar.undo.title": "Visszavonás (Ctrl-Z)", "pad.toolbar.undo.title": "Visszavonás (Ctrl-Z)",
@ -28,16 +30,16 @@
"pad.toolbar.timeslider.title": "Időcsúszka", "pad.toolbar.timeslider.title": "Időcsúszka",
"pad.toolbar.savedRevision.title": "Revízió mentése", "pad.toolbar.savedRevision.title": "Revízió mentése",
"pad.toolbar.settings.title": "Beállítások", "pad.toolbar.settings.title": "Beállítások",
"pad.toolbar.embed.title": "Notesz beágyazása és megosztása", "pad.toolbar.embed.title": "Jegyzetfüzet beágyazása és megosztása",
"pad.toolbar.showusers.title": "Notesz felhasználóinak megmutatása", "pad.toolbar.showusers.title": "Jegyzetfüzet felhasználóinak megmutatása",
"pad.colorpicker.save": "Mentés", "pad.colorpicker.save": "Mentés",
"pad.colorpicker.cancel": "Mégsem", "pad.colorpicker.cancel": "Mégsem",
"pad.loading": "Betöltés…", "pad.loading": "Betöltés…",
"pad.noCookie": "Nem található a süti. Engedélyezd a böngésződben a sütik használatát!", "pad.noCookie": "Nem található a süti. Engedélyezd a böngésződben a sütik használatát! A munkamenet és a beállítások nem kerülnek mentésre a látogatások között. Ennek oka lehet az, hogy az Etherpad egyes böngészőkben szerepel az iFrame-ben. Ellenőrizze, hogy az Etherpad ugyanabban az altartomány / tartományban van-e, mint a szülő iFrame",
"pad.passwordRequired": "Jelszóra van szükséged ezen notesz eléréséhez", "pad.passwordRequired": "Jelszóra van szükséged ezen jegyzetfüzet eléréséhez",
"pad.permissionDenied": "Nincs engedélyed ezen notesz eléréséhez", "pad.permissionDenied": "Nincs engedélyed ezen jegyzetfüzet eléréséhez",
"pad.wrongPassword": "A jelszó rossz volt", "pad.wrongPassword": "A jelszó rossz volt",
"pad.settings.padSettings": "Notesz beállításai", "pad.settings.padSettings": "Jegyzetfüzet beállításai",
"pad.settings.myView": "Az én nézetem", "pad.settings.myView": "Az én nézetem",
"pad.settings.stickychat": "Mindig mutasd a csevegés-dobozt", "pad.settings.stickychat": "Mindig mutasd a csevegés-dobozt",
"pad.settings.chatandusers": "Csevegés és felhasználók mutatása", "pad.settings.chatandusers": "Csevegés és felhasználók mutatása",
@ -47,24 +49,26 @@
"pad.settings.fontType": "Betűtípus:", "pad.settings.fontType": "Betűtípus:",
"pad.settings.fontType.normal": "Szokásos", "pad.settings.fontType.normal": "Szokásos",
"pad.settings.language": "Nyelv:", "pad.settings.language": "Nyelv:",
"pad.settings.about": "Névjegy",
"pad.settings.poweredBy": "Működteti",
"pad.importExport.import_export": "Import/export", "pad.importExport.import_export": "Import/export",
"pad.importExport.import": "Tetszőleges szövegfájl vagy dokumentum feltöltése", "pad.importExport.import": "Tetszőleges szövegfájl vagy dokumentum feltöltése",
"pad.importExport.importSuccessful": "Siker!", "pad.importExport.importSuccessful": "Siker!",
"pad.importExport.export": "Jelenlegi notesz exportálása így:", "pad.importExport.export": "Jelenlegi jegyzetfüzet exportálása így:",
"pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML", "pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Sima szöveg", "pad.importExport.exportplain": "Sima szöveg",
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document formátum)", "pad.importExport.exportopen": "ODF (Open Document formátum)",
"pad.importExport.abiword.innerHTML": "Csak szöveges, vagy HTML formátumokból importálhatsz. A speciális importálási funkciókért kérjük <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">telepítsd az AbiWord-öt</a>.", "pad.importExport.abiword.innerHTML": "Csak szöveges, vagy HTML formátumokból importálhat. A haladó importálási szolgáltatásért kérjük <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">telepítse a AbiWord vagy a LibreOffice alkalmazást</a>.",
"pad.modals.connected": "Kapcsolódva.", "pad.modals.connected": "Kapcsolódva.",
"pad.modals.reconnecting": "Újrakapcsolódás a noteszhez...", "pad.modals.reconnecting": "Újrakapcsolódás a jegyzetfüzethez…",
"pad.modals.forcereconnect": "Újrakapcsolódás kényszerítése", "pad.modals.forcereconnect": "Újrakapcsolódás kényszerítése",
"pad.modals.reconnecttimer": "Megpróbálok újracsatlakozni ennyi múlva:", "pad.modals.reconnecttimer": "Megpróbálok újracsatlakozni ennyi múlva:",
"pad.modals.cancel": "Mégse", "pad.modals.cancel": "Mégse",
"pad.modals.userdup": "Új ablakban megnyitva", "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.explanation": "Úgy tűnik, ez a jegyzetfüzet 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.", "pad.modals.userdup.advice": "Kapcsolódj újra, ha ezt az ablakot akarod használni.",
"pad.modals.unauth": "Nincs rá jogosultságod", "pad.modals.unauth": "Nincs rá jogosultságod",
"pad.modals.unauth.explanation": "A jogosultságaid megváltoztak, miközben ezt az oldalt nézted. Próbálj meg újrakapcsolódni!", "pad.modals.unauth.explanation": "A jogosultságaid megváltoztak, miközben ezt az oldalt nézted. Próbálj meg újrakapcsolódni!",
@ -77,34 +81,37 @@
"pad.modals.slowcommit.cause": "Valószínűleg az internetkapcsolattal van probléma.", "pad.modals.slowcommit.cause": "Valószínűleg az internetkapcsolattal van probléma.",
"pad.modals.badChangeset.explanation": "Szerkesztéseded a szinkronizációs szerver illegálisnak sorolta be.", "pad.modals.badChangeset.explanation": "Szerkesztéseded a szinkronizációs szerver illegálisnak sorolta be.",
"pad.modals.badChangeset.cause": "Ennek oka lehet egy rossz szerver konfiguráció, vagy más váratlan viselkedés. Ha úgy érzi, ez hiba eredménye, lépjen kapcsolatba a szolgáltatás adminisztrátorával. Próbáljon meg újrakapcsolódni a szerkesztés folytatásához.", "pad.modals.badChangeset.cause": "Ennek oka lehet egy rossz szerver konfiguráció, vagy más váratlan viselkedés. Ha úgy érzi, ez hiba eredménye, lépjen kapcsolatba a szolgáltatás adminisztrátorával. Próbáljon meg újrakapcsolódni a szerkesztés folytatásához.",
"pad.modals.corruptPad.explanation": "A notesz, amit megpróbálsz elérni, sérült.", "pad.modals.corruptPad.explanation": "A jegyzetfüzet, amit megpróbálsz elérni, sérült.",
"pad.modals.corruptPad.cause": "Ennek oka lehet egy rossz szerver konfiguráció, vagy más váratlan viselkedés. Kérjük, lépj kapcsolatba a szolgáltatás adminisztrátorával.", "pad.modals.corruptPad.cause": "Ennek oka lehet egy rossz szerver konfiguráció, vagy más váratlan viselkedés. Kérjük, lépj kapcsolatba a szolgáltatás adminisztrátorával.",
"pad.modals.deleted": "Törölve.", "pad.modals.deleted": "Törölve.",
"pad.modals.deleted.explanation": "Ez a notesz el lett távolítva.", "pad.modals.deleted.explanation": "Ez a jegyzetfüzet el lett távolítva.",
"pad.modals.rateLimited": "Korlátozott.",
"pad.modals.rateLimited.explanation": "Túl sok üzenetet küldött erre a jegyzetfüzetre, így a kapcsolat bontva lett.",
"pad.modals.disconnected": "Kapcsolat bontva.", "pad.modals.disconnected": "Kapcsolat bontva.",
"pad.modals.disconnected.explanation": "A szerverrel való kapcsolat megszűnt", "pad.modals.disconnected.explanation": "A szerverrel való kapcsolat megszűnt",
"pad.modals.disconnected.cause": "Lehet, hogy a szerver nem elérhető. Kérlek, értesítsd a szolgáltatás adminisztrátorát, ha a probléma tartósan fennáll.", "pad.modals.disconnected.cause": "Lehet, hogy a szerver nem elérhető. Kérlek, értesítsd a szolgáltatás adminisztrátorát, ha a probléma tartósan fennáll.",
"pad.share": "Notesz megosztása", "pad.share": "Jegyzetfüzet megosztása",
"pad.share.readonly": "Csak olvasható", "pad.share.readonly": "Csak olvasható",
"pad.share.link": "Hivatkozás", "pad.share.link": "Hivatkozás",
"pad.share.emebdcode": "URL beágyazása", "pad.share.emebdcode": "URL beágyazása",
"pad.chat": "Csevegés", "pad.chat": "Csevegés",
"pad.chat.title": "A noteszhez tartozó csevegés megnyitása.", "pad.chat.title": "A jegyzetfüzethez tartozó csevegés megnyitása.",
"pad.chat.loadmessages": "További üzenetek betöltése", "pad.chat.loadmessages": "További üzenetek betöltése",
"pad.chat.stick.title": "Csevegés a képernyőre", "pad.chat.stick.title": "Csevegés a képernyőre",
"pad.chat.writeMessage.placeholder": "Írja az üzenetét ide", "pad.chat.writeMessage.placeholder": "Írja az üzenetét ide",
"timeslider.followContents": "Kövesse a jegyzetfüzet tartalmának frissítéseit",
"timeslider.pageTitle": "{{appTitle}} időcsúszka", "timeslider.pageTitle": "{{appTitle}} időcsúszka",
"timeslider.toolbar.returnbutton": "Vissza a noteszhez", "timeslider.toolbar.returnbutton": "Vissza a jegyzetfüzethez",
"timeslider.toolbar.authors": "Szerzők:", "timeslider.toolbar.authors": "Szerzők:",
"timeslider.toolbar.authorsList": "Nincsenek szerzők", "timeslider.toolbar.authorsList": "Nincsenek szerzők",
"timeslider.toolbar.exportlink.title": "Exportálás", "timeslider.toolbar.exportlink.title": "Exportálás",
"timeslider.exportCurrent": "Jelenlegi változat exportálása így:", "timeslider.exportCurrent": "Jelenlegi változat exportálása így:",
"timeslider.version": "{{version}} verzió", "timeslider.version": "{{version}} verzió",
"timeslider.saved": "{{year}}. {{month}} {{day}}-n elmentve", "timeslider.saved": "{{year}}. {{month}} {{day}}-n elmentve",
"timeslider.playPause": "Notesz tartalom visszajátszása / leállítása", "timeslider.playPause": "Jegyzetfüzet tartalom visszajátszása/leállítása",
"timeslider.backRevision": "Egy revízióval vissza a noteszben", "timeslider.backRevision": "Egy revízióval vissza a jegyzetfüzetben",
"timeslider.forwardRevision": "Egy revízióval előre a noteszben", "timeslider.forwardRevision": "Egy revízióval előre a jegyzetfüzetben",
"timeslider.dateformat": "{{year}}/{{month}}/{{day}} {{hours}}:{{minutes}}:{{seconds}}", "timeslider.dateformat": "{{year}}.{{month}}.{{day}}. {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "január", "timeslider.month.january": "január",
"timeslider.month.february": "február", "timeslider.month.february": "február",
"timeslider.month.march": "március", "timeslider.month.march": "március",
@ -125,14 +132,16 @@
"pad.userlist.guest": "Vendég", "pad.userlist.guest": "Vendég",
"pad.userlist.deny": "Megtagad", "pad.userlist.deny": "Megtagad",
"pad.userlist.approve": "Jóváhagy", "pad.userlist.approve": "Jóváhagy",
"pad.editbar.clearcolors": "A szerzőséget jelző színeket törlöd a teljes dokumentumból?", "pad.editbar.clearcolors": "A szerzőséget jelző színeket törli a teljes dokumentumból? Ez nem vonható vissza.",
"pad.impexp.importbutton": "Importálás most", "pad.impexp.importbutton": "Importálás most",
"pad.impexp.importing": "Importálás…", "pad.impexp.importing": "Importálás…",
"pad.impexp.confirmimport": "Egy fájl importálása felülírja a jelenlegi szöveget a noteszben. Biztos hogy folytatod?", "pad.impexp.confirmimport": "Egy fájl importálása felülírja a jelenlegi szöveget a jegyzetfüzetben. Biztosan folytatja?",
"pad.impexp.convertFailed": "Nem tudtuk importálni ezt a fájlt. Kérjük, használj másik dokumentum formátumot, vagy kézzel másold és illeszd be a tartalmat", "pad.impexp.convertFailed": "Nem tudtuk importálni ezt a fájlt. Kérjük, használj másik dokumentum formátumot, vagy kézzel másold és illeszd be a tartalmat",
"pad.impexp.padHasData": "Nem tudjuk importálni ezt a fájlt, mert ez a notesz már megváltozott, kérjük, importálj egy új noteszba.", "pad.impexp.padHasData": "Nem tudjuk importálni ezt a fájlt, mert ez a jegyzetfüzet már megváltozott, kérjük, importálj egy új jegyzetfüzetbe.",
"pad.impexp.uploadFailed": "A feltöltés sikertelen, próbáld meg újra", "pad.impexp.uploadFailed": "A feltöltés sikertelen, próbáld meg újra",
"pad.impexp.importfailed": "Az importálás nem sikerült", "pad.impexp.importfailed": "Az importálás nem sikerült",
"pad.impexp.copypaste": "Kérjük másold be", "pad.impexp.copypaste": "Kérjük másold be",
"pad.impexp.exportdisabled": "{{type}} formátumba az exportálás nem engedélyezett. Kérjük, a részletekért fordulj a rendszeradminisztrátorhoz." "pad.impexp.exportdisabled": "{{type}} formátumba az exportálás nem engedélyezett. Kérjük, a részletekért fordulj a rendszeradminisztrátorhoz.",
"pad.impexp.maxFileSize": "Túl nagy a fájl. Vegye fel a kapcsolatot a webhelygazdájával, hogy növelje az importálható fájl méretét",
"pad.impexp.permission": "Az importálás le van tiltva, mert soha nem járult hozzá ehhez a jegyzetfüzethez. Kérjük, járuljon hozzá legalább egyszer az importálás előtt"
} }

View file

@ -3,25 +3,27 @@
"authors": [ "authors": [
"Beta16", "Beta16",
"Gianfranco", "Gianfranco",
"Jack",
"Macofe", "Macofe",
"Muxator", "Muxator",
"Nivit", "Nivit",
"Vituzzu" "Vituzzu"
] ]
}, },
"index.newPad": "Nuovo Pad", "index.newPad": "Nuovo pad",
"index.createOpenPad": "o creare o aprire un Pad con il nome:", "index.createOpenPad": "o crea/apre un pad con il nome:",
"pad.toolbar.bold.title": "Grassetto (Ctrl-B)", "index.openPad": "apri un Pad esistente col nome:",
"pad.toolbar.italic.title": "Corsivo (Ctrl-I)", "pad.toolbar.bold.title": "Grassetto (Ctrl+B)",
"pad.toolbar.underline.title": "Sottolineato (Ctrl-U)", "pad.toolbar.italic.title": "Corsivo (Ctrl+I)",
"pad.toolbar.underline.title": "Sottolineato (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Barrato (Ctrl+5)", "pad.toolbar.strikethrough.title": "Barrato (Ctrl+5)",
"pad.toolbar.ol.title": "Elenco numerato (Ctrl+Shift+N)", "pad.toolbar.ol.title": "Elenco numerato (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Elenco puntato (Ctrl+Shift+L)", "pad.toolbar.ul.title": "Elenco puntato (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Indentazione (TAB)", "pad.toolbar.indent.title": "Indentazione (TAB)",
"pad.toolbar.unindent.title": "Riduci indentazione (Shift+TAB)", "pad.toolbar.unindent.title": "Riduci indentazione (Shift+TAB)",
"pad.toolbar.undo.title": "Annulla (Ctrl-Z)", "pad.toolbar.undo.title": "Annulla (Ctrl+Z)",
"pad.toolbar.redo.title": "Ripeti (Ctrl-Y)", "pad.toolbar.redo.title": "Ripeti (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Elimina i colori che indicano gli autori (Ctrl+Shift+C)", "pad.toolbar.clearAuthorship.title": "Elimina i colori degli autori (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Importa/esporta da/a diversi formati di file", "pad.toolbar.import_export.title": "Importa/esporta da/a diversi formati di file",
"pad.toolbar.timeslider.title": "Presentazione cronologia", "pad.toolbar.timeslider.title": "Presentazione cronologia",
"pad.toolbar.savedRevision.title": "Versione salvata", "pad.toolbar.savedRevision.title": "Versione salvata",
@ -31,7 +33,7 @@
"pad.colorpicker.save": "Salva", "pad.colorpicker.save": "Salva",
"pad.colorpicker.cancel": "Annulla", "pad.colorpicker.cancel": "Annulla",
"pad.loading": "Caricamento in corso…", "pad.loading": "Caricamento in corso…",
"pad.noCookie": "Il cookie non è stato trovato. Consenti i cookie nel tuo browser!", "pad.noCookie": "Il cookie non è stato trovato. Consenti i cookie nel tuo browser! La sessione e le impostazioni non verranno salvate tra le diverse visite. Ciò può essere dovuto al fatto che Etherpad è stato incluso in un iFrame in alcuni browser. Assicurati che Etherpad si trovi sullo stesso sottodominio/dominio dell'iFrame principale",
"pad.passwordRequired": "Per accedere a questo Pad è necessaria una password", "pad.passwordRequired": "Per accedere a questo Pad è necessaria una password",
"pad.permissionDenied": "Non si dispone dei permessi necessari per accedere a questo Pad", "pad.permissionDenied": "Non si dispone dei permessi necessari per accedere a questo Pad",
"pad.wrongPassword": "La password è sbagliata", "pad.wrongPassword": "La password è sbagliata",
@ -45,6 +47,8 @@
"pad.settings.fontType": "Tipo di carattere:", "pad.settings.fontType": "Tipo di carattere:",
"pad.settings.fontType.normal": "Normale", "pad.settings.fontType.normal": "Normale",
"pad.settings.language": "Lingua:", "pad.settings.language": "Lingua:",
"pad.settings.about": "Informazioni",
"pad.settings.poweredBy": "Realizzato con",
"pad.importExport.import_export": "Importazione/esportazione", "pad.importExport.import_export": "Importazione/esportazione",
"pad.importExport.import": "Carica un file di testo o un documento", "pad.importExport.import": "Carica un file di testo o un documento",
"pad.importExport.importSuccessful": "Riuscito!", "pad.importExport.importSuccessful": "Riuscito!",
@ -70,9 +74,9 @@
"pad.modals.looping.cause": "Forse sei connesso attraverso un firewall o un server proxy non compatibili.", "pad.modals.looping.cause": "Forse sei connesso attraverso un firewall o un server proxy non compatibili.",
"pad.modals.initsocketfail": "Il server non è raggiungibile.", "pad.modals.initsocketfail": "Il server non è raggiungibile.",
"pad.modals.initsocketfail.explanation": "Impossibile connettersi al server di sincronizzazione.", "pad.modals.initsocketfail.explanation": "Impossibile connettersi al server di sincronizzazione.",
"pad.modals.initsocketfail.cause": "Questo probabilmente è dovuto a un problema con il tuo browser o con la tua connessione a internet.", "pad.modals.initsocketfail.cause": "Questo probabilmente è dovuto a un problema con il browser o con la tua connessione internet.",
"pad.modals.slowcommit.explanation": "Il server non risponde.", "pad.modals.slowcommit.explanation": "Il server non risponde.",
"pad.modals.slowcommit.cause": "Questo potrebbe essere dovuto a problemi con la connettività di rete.", "pad.modals.slowcommit.cause": "Questo potrebbe essere dovuto a problemi di connettività di rete.",
"pad.modals.badChangeset.explanation": "Una modifica che hai fatto è stata considerata illegale dal server di sincronizzazione.", "pad.modals.badChangeset.explanation": "Una modifica che hai fatto è stata considerata illegale dal server di sincronizzazione.",
"pad.modals.badChangeset.cause": "Ciò potrebbe essere causato da una errata configurazione del server o qualche altro comportamento imprevisto. Si prega di contattare l'amministratore del servizio, se si ritiene che questo sia un errore. Prova a riconnetterti per tentare di continuare a modificare.", "pad.modals.badChangeset.cause": "Ciò potrebbe essere causato da una errata configurazione del server o qualche altro comportamento imprevisto. Si prega di contattare l'amministratore del servizio, se si ritiene che questo sia un errore. Prova a riconnetterti per tentare di continuare a modificare.",
"pad.modals.corruptPad.explanation": "Il pad a cui stai tentando di accedere è danneggiato.", "pad.modals.corruptPad.explanation": "Il pad a cui stai tentando di accedere è danneggiato.",
@ -132,5 +136,7 @@
"pad.impexp.uploadFailed": "Caricamento non riuscito, riprovare", "pad.impexp.uploadFailed": "Caricamento non riuscito, riprovare",
"pad.impexp.importfailed": "Importazione fallita", "pad.impexp.importfailed": "Importazione fallita",
"pad.impexp.copypaste": "Si prega di copiare e incollare", "pad.impexp.copypaste": "Si prega di copiare e incollare",
"pad.impexp.exportdisabled": "L'esportazione come {{type}} è disabilitata. Contattare l'amministratore per i dettagli." "pad.impexp.exportdisabled": "L'esportazione come {{type}} è disabilitata. Contattare l'amministratore per i dettagli.",
"pad.impexp.maxFileSize": "File troppo grande. Contatta l'amministratore del sito per incrementare la dimensione consentita per l'importazione",
"pad.impexp.permission": "L'importazione è disabilitata perché non hai mai contribuito a questo pad. Per favore, contribuisci almeno una volta, prima di fare importazioni"
} }

View file

@ -10,6 +10,7 @@
}, },
"index.newPad": "新規作成", "index.newPad": "新規作成",
"index.createOpenPad": "または作成/編集するパッド名を入力:", "index.createOpenPad": "または作成/編集するパッド名を入力:",
"index.openPad": "次の名称の既存の Pad を開く:",
"pad.toolbar.bold.title": "太字 (Ctrl+B)", "pad.toolbar.bold.title": "太字 (Ctrl+B)",
"pad.toolbar.italic.title": "斜体 (Ctrl+I)", "pad.toolbar.italic.title": "斜体 (Ctrl+I)",
"pad.toolbar.underline.title": "下線 (Ctrl+U)", "pad.toolbar.underline.title": "下線 (Ctrl+U)",
@ -30,7 +31,7 @@
"pad.colorpicker.save": "保存", "pad.colorpicker.save": "保存",
"pad.colorpicker.cancel": "キャンセル", "pad.colorpicker.cancel": "キャンセル",
"pad.loading": "読み込み中...", "pad.loading": "読み込み中...",
"pad.noCookie": "クッキーが見つかりません。ブラウザの設定でクッキーの使用を許可してください。", "pad.noCookie": "Cookie could not be found. Please allow cookies in your browser! Your session and settings will not be saved between visits. \n\nクッキーが見つかりません。ブラウザの設定でクッキーの使用を許可するまで、アクセスの記録や設定は引き継がれません。原因はブラウザによって Etherpad が iFrame に組み込まれたからと考えられます。親ドメインの iFrame と同じドメイン/サブドメインに置かれているかどうか、Etherpad の設定を確認してください。",
"pad.passwordRequired": "このパッドにアクセスするにはパスワードが必要です", "pad.passwordRequired": "このパッドにアクセスするにはパスワードが必要です",
"pad.permissionDenied": "あなたにはこのパッドへのアクセス許可がありません", "pad.permissionDenied": "あなたにはこのパッドへのアクセス許可がありません",
"pad.wrongPassword": "パスワードが間違っています", "pad.wrongPassword": "パスワードが間違っています",
@ -44,6 +45,8 @@
"pad.settings.fontType": "フォントの種類:", "pad.settings.fontType": "フォントの種類:",
"pad.settings.fontType.normal": "通常", "pad.settings.fontType.normal": "通常",
"pad.settings.language": "言語:", "pad.settings.language": "言語:",
"pad.settings.about": "このアプリについて",
"pad.settings.poweredBy": "提供",
"pad.importExport.import_export": "インポート/エクスポート", "pad.importExport.import_export": "インポート/エクスポート",
"pad.importExport.import": "あらゆるテキストファイルや文書をアップロードできます", "pad.importExport.import": "あらゆるテキストファイルや文書をアップロードできます",
"pad.importExport.importSuccessful": "完了しました。", "pad.importExport.importSuccessful": "完了しました。",
@ -78,6 +81,8 @@
"pad.modals.corruptPad.cause": "これはサーバーの構成不良か、予期せぬ挙動を見せたために発生した事象である可能性があります。当サービス管理者にお問い合わせください。", "pad.modals.corruptPad.cause": "これはサーバーの構成不良か、予期せぬ挙動を見せたために発生した事象である可能性があります。当サービス管理者にお問い合わせください。",
"pad.modals.deleted": "削除されました。", "pad.modals.deleted": "削除されました。",
"pad.modals.deleted.explanation": "このパッドは削除されました。", "pad.modals.deleted.explanation": "このパッドは削除されました。",
"pad.modals.rateLimited": "速度制限中です。",
"pad.modals.rateLimited.explanation": "パッドに送ったメッセージ件数が多すぎたため接続が解除されました。",
"pad.modals.disconnected": "切断されました。", "pad.modals.disconnected": "切断されました。",
"pad.modals.disconnected.explanation": "サーバーとの接続が失われました", "pad.modals.disconnected.explanation": "サーバーとの接続が失われました",
"pad.modals.disconnected.cause": "サーバーを利用できない可能性があります。この問題が解決しない場合はサービスの管理者にお知らせください。", "pad.modals.disconnected.cause": "サーバーを利用できない可能性があります。この問題が解決しない場合はサービスの管理者にお知らせください。",
@ -90,6 +95,7 @@
"pad.chat.loadmessages": "その他のメッセージを読み込む", "pad.chat.loadmessages": "その他のメッセージを読み込む",
"pad.chat.stick.title": "チャットを画面に貼り付ける", "pad.chat.stick.title": "チャットを画面に貼り付ける",
"pad.chat.writeMessage.placeholder": "ここにメッセージを書き込んでください", "pad.chat.writeMessage.placeholder": "ここにメッセージを書き込んでください",
"timeslider.followContents": "パッドの内容の更新をフォロー",
"timeslider.pageTitle": "{{appTitle}} タイムスライダー", "timeslider.pageTitle": "{{appTitle}} タイムスライダー",
"timeslider.toolbar.returnbutton": "パッドに戻る", "timeslider.toolbar.returnbutton": "パッドに戻る",
"timeslider.toolbar.authors": "作者:", "timeslider.toolbar.authors": "作者:",
@ -97,7 +103,7 @@
"timeslider.toolbar.exportlink.title": "エクスポート", "timeslider.toolbar.exportlink.title": "エクスポート",
"timeslider.exportCurrent": "現在の版をエクスポートする形式:", "timeslider.exportCurrent": "現在の版をエクスポートする形式:",
"timeslider.version": "バージョン {{version}}", "timeslider.version": "バージョン {{version}}",
"timeslider.saved": "| {{year}}年{{month}}{{day}}日に保存", "timeslider.saved": "{{year}}年{{month}}{{day}}日に保存",
"timeslider.playPause": "パッドの過去の内容を再生/一時停止", "timeslider.playPause": "パッドの過去の内容を再生/一時停止",
"timeslider.backRevision": "前の版に戻る", "timeslider.backRevision": "前の版に戻る",
"timeslider.forwardRevision": "次の版に進む", "timeslider.forwardRevision": "次の版に進む",

View file

@ -1,6 +1,7 @@
{ {
"@metadata": { "@metadata": {
"authors": [ "authors": [
"Pichnat Thong",
"Sovichet", "Sovichet",
"វ័ណថារិទ្ធ" "វ័ណថារិទ្ធ"
] ]
@ -36,6 +37,8 @@
"pad.settings.fontType": "ប្រភេទពុម្ពអក្សរ៖", "pad.settings.fontType": "ប្រភេទពុម្ពអក្សរ៖",
"pad.settings.fontType.normal": "ធម្មតា", "pad.settings.fontType.normal": "ធម្មតា",
"pad.settings.language": "ភាសា៖", "pad.settings.language": "ភាសា៖",
"pad.settings.about": "អំពី",
"pad.settings.poweredBy": "ពលុបត្ថម្ភដោយ",
"pad.importExport.import_export": "នាំចូល/នាំចេញ", "pad.importExport.import_export": "នាំចូល/នាំចេញ",
"pad.importExport.import": "ផ្ទុក​ឡើង​ឯកសារ​អត្ថបទ​ណាមួយ", "pad.importExport.import": "ផ្ទុក​ឡើង​ឯកសារ​អត្ថបទ​ណាមួយ",
"pad.importExport.importSuccessful": "ដោយជោគជ័យ!", "pad.importExport.importSuccessful": "ដោយជោគជ័យ!",

View file

@ -2,6 +2,8 @@
"@metadata": { "@metadata": {
"authors": [ "authors": [
"CYAN", "CYAN",
"Codenstory",
"Ellif",
"Hym411", "Hym411",
"Kurousagi", "Kurousagi",
"Revi", "Revi",
@ -46,6 +48,8 @@
"pad.settings.fontType": "글꼴 종류:", "pad.settings.fontType": "글꼴 종류:",
"pad.settings.fontType.normal": "보통", "pad.settings.fontType.normal": "보통",
"pad.settings.language": "언어:", "pad.settings.language": "언어:",
"pad.settings.about": "소개",
"pad.settings.poweredBy": "제공:",
"pad.importExport.import_export": "가져오기/내보내기", "pad.importExport.import_export": "가져오기/내보내기",
"pad.importExport.import": "텍스트 파일이나 문서 올리기", "pad.importExport.import": "텍스트 파일이나 문서 올리기",
"pad.importExport.importSuccessful": "성공!", "pad.importExport.importSuccessful": "성공!",
@ -129,9 +133,11 @@
"pad.impexp.importing": "가져오는 중...", "pad.impexp.importing": "가져오는 중...",
"pad.impexp.confirmimport": "파일을 가져오면 패드의 현재 텍스트를 덮어쓰게 됩니다. 진행하시겠습니까?", "pad.impexp.confirmimport": "파일을 가져오면 패드의 현재 텍스트를 덮어쓰게 됩니다. 진행하시겠습니까?",
"pad.impexp.convertFailed": "이 파일을 가져올 수 없습니다. 다른 문서 형식을 사용하거나 수동으로 복사하여 붙여넣으세요", "pad.impexp.convertFailed": "이 파일을 가져올 수 없습니다. 다른 문서 형식을 사용하거나 수동으로 복사하여 붙여넣으세요",
"pad.impexp.padHasData": "우리는 이 파일을 가져올 수 없습니다. 이 패드는 이미 수정되었으니, 새 패드를 가져와 주십시오", "pad.impexp.padHasData": "이 파일을 가져올 수 없습니다. 이 패드는 이미 수정되었으니, 새 패드를 가져와 주십시오",
"pad.impexp.uploadFailed": "올리기를 실패했습니다. 다시 시도하세요", "pad.impexp.uploadFailed": "올리기를 실패했습니다. 다시 시도하세요",
"pad.impexp.importfailed": "가져오기를 실패했습니다", "pad.impexp.importfailed": "가져오기를 실패했습니다",
"pad.impexp.copypaste": "복사하여 붙여넣으세요", "pad.impexp.copypaste": "복사하여 붙여넣으세요",
"pad.impexp.exportdisabled": "{{type}} 형식으로 내보내기가 비활성화되어 있습니다. 자세한 내용은 시스템 관리자에게 문의하시기 바랍니다." "pad.impexp.exportdisabled": "{{type}} 형식으로 내보내기가 비활성화되어 있습니다. 자세한 내용은 시스템 관리자에게 문의하시기 바랍니다.",
"pad.impexp.maxFileSize": "파일의 용량이 너무 큽니다. 가져올 파일의 허용 크기를 늘리려면 사이트 관리자에게 문의하십시오",
"pad.impexp.permission": "이 패드로 기여한 적이 없으므로 가져오기가 비활성화됩니다. 가져오기 전에 적어도 한 번은 기여해 주십시오"
} }

View file

@ -35,6 +35,7 @@
"pad.settings.rtlcheck": "Bila naverok ji raste ber bi çepe be xwendin?", "pad.settings.rtlcheck": "Bila naverok ji raste ber bi çepe be xwendin?",
"pad.settings.fontType": "Tîpa nivîsê:", "pad.settings.fontType": "Tîpa nivîsê:",
"pad.settings.language": "Ziman:", "pad.settings.language": "Ziman:",
"pad.settings.about": "Derbar",
"pad.importExport.importSuccessful": "Biserketî!", "pad.importExport.importSuccessful": "Biserketî!",
"pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML", "pad.importExport.exporthtml": "HTML",

View file

@ -34,6 +34,8 @@
"pad.settings.fontType": "Schrëftart:", "pad.settings.fontType": "Schrëftart:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Sprooch:", "pad.settings.language": "Sprooch:",
"pad.settings.about": "Iwwer",
"pad.settings.poweredBy": "Zur Verfügung gestallt vu(n)",
"pad.importExport.import_export": "Import/Export", "pad.importExport.import_export": "Import/Export",
"pad.importExport.import": "Text-Fichier oder Dokument eroplueden", "pad.importExport.import": "Text-Fichier oder Dokument eroplueden",
"pad.importExport.importSuccessful": "Erfollegräich", "pad.importExport.importSuccessful": "Erfollegräich",

View file

@ -8,6 +8,7 @@
}, },
"index.newPad": "Нова тетратка", "index.newPad": "Нова тетратка",
"index.createOpenPad": "или направете/отворете тетратка со името:", "index.createOpenPad": "или направете/отворете тетратка со името:",
"index.openPad": "отвори постоечка тетратка наречена:",
"pad.toolbar.bold.title": "Задебелено (Ctrl-B)", "pad.toolbar.bold.title": "Задебелено (Ctrl-B)",
"pad.toolbar.italic.title": "Косо (Ctrl-I)", "pad.toolbar.italic.title": "Косо (Ctrl-I)",
"pad.toolbar.underline.title": "Подвлечено (Ctrl-U)", "pad.toolbar.underline.title": "Подвлечено (Ctrl-U)",
@ -28,7 +29,7 @@
"pad.colorpicker.save": "Зачувај", "pad.colorpicker.save": "Зачувај",
"pad.colorpicker.cancel": "Откажи", "pad.colorpicker.cancel": "Откажи",
"pad.loading": "Вчитувам...", "pad.loading": "Вчитувам...",
"pad.noCookie": "Не можев да го најдам колачето. Овозможете колачиња во вашиот прелистувач!", "pad.noCookie": "Не можев да го најдам колачето. Овозможете колачиња во вашиот прелистувач! Вашата седница и нагодувања нема да бидат зачувани за следната посета. Ова можеби се должи на тоа што Etherpad е вклучен во iFrame во некои прелистувачи. Проверете дали Etherpad е на истиот поддомен/домен како матичниот iFrame",
"pad.passwordRequired": "Потребна е лозинка за пристап", "pad.passwordRequired": "Потребна е лозинка за пристап",
"pad.permissionDenied": "За овде не е потребна дозвола за пристап", "pad.permissionDenied": "За овде не е потребна дозвола за пристап",
"pad.wrongPassword": "Погрешна лозинка", "pad.wrongPassword": "Погрешна лозинка",
@ -42,6 +43,8 @@
"pad.settings.fontType": "Тип на фонт:", "pad.settings.fontType": "Тип на фонт:",
"pad.settings.fontType.normal": "Нормален", "pad.settings.fontType.normal": "Нормален",
"pad.settings.language": "Јазик:", "pad.settings.language": "Јазик:",
"pad.settings.about": "За додатоков",
"pad.settings.poweredBy": "Овозможено од",
"pad.importExport.import_export": "Увоз/Извоз", "pad.importExport.import_export": "Увоз/Извоз",
"pad.importExport.import": "Подигање на било каква текстуална податотека или документ", "pad.importExport.import": "Подигање на било каква текстуална податотека или документ",
"pad.importExport.importSuccessful": "Успешно!", "pad.importExport.importSuccessful": "Успешно!",
@ -76,6 +79,8 @@
"pad.modals.corruptPad.cause": "Ова може да се должи на погрешна поставеност на опслужувачот или некое друго неочекувано поведение. Обратете се кај администраторот.", "pad.modals.corruptPad.cause": "Ова може да се должи на погрешна поставеност на опслужувачот или некое друго неочекувано поведение. Обратете се кај администраторот.",
"pad.modals.deleted": "Избришано.", "pad.modals.deleted": "Избришано.",
"pad.modals.deleted.explanation": "Оваа тетратка е отстранета.", "pad.modals.deleted.explanation": "Оваа тетратка е отстранета.",
"pad.modals.rateLimited": "Ограничено по стапка.",
"pad.modals.rateLimited.explanation": "Испративте премногу пораки на тетраткава, па затоа таа ве исклучи.",
"pad.modals.disconnected": "Врската е прекината.", "pad.modals.disconnected": "Врската е прекината.",
"pad.modals.disconnected.explanation": "Врската со опслужувачот е прекината", "pad.modals.disconnected.explanation": "Врската со опслужувачот е прекината",
"pad.modals.disconnected.cause": "Опслужувачот може да е недостапен. Известете го администраторот ако ова продолжи да ви се случува.", "pad.modals.disconnected.cause": "Опслужувачот може да е недостапен. Известете го администраторот ако ова продолжи да ви се случува.",
@ -88,6 +93,7 @@
"pad.chat.loadmessages": "Вчитај уште пораки", "pad.chat.loadmessages": "Вчитај уште пораки",
"pad.chat.stick.title": "Залепи го разговорот на екранот", "pad.chat.stick.title": "Залепи го разговорот на екранот",
"pad.chat.writeMessage.placeholder": "Тука напишете порака", "pad.chat.writeMessage.placeholder": "Тука напишете порака",
"timeslider.followContents": "Следи ги подновите во содржината на тетратката",
"timeslider.pageTitle": "{{appTitle}} Историски преглед", "timeslider.pageTitle": "{{appTitle}} Историски преглед",
"timeslider.toolbar.returnbutton": "Назад на тетратката", "timeslider.toolbar.returnbutton": "Назад на тетратката",
"timeslider.toolbar.authors": "Автори:", "timeslider.toolbar.authors": "Автори:",

View file

@ -34,7 +34,7 @@
"pad.colorpicker.save": "സേവ് ചെയ്യുക", "pad.colorpicker.save": "സേവ് ചെയ്യുക",
"pad.colorpicker.cancel": "റദ്ദാക്കുക", "pad.colorpicker.cancel": "റദ്ദാക്കുക",
"pad.loading": "ശേഖരിക്കുന്നു...", "pad.loading": "ശേഖരിക്കുന്നു...",
"pad.noCookie": "കുക്കി കണ്ടെത്താനായില്ല. ദയവായി താങ്കളുടെ ബ്രൗസറിൽ കുക്കികൾ അനുവദിക്കുക!", "pad.noCookie": "കുക്കി കണ്ടെത്താനായില്ല. ദയവായി താങ്കളുടെ ബ്രൗസറിൽ കുക്കികൾ അനുവദിക്കുക! തിരുത്തലുകൾക്കിടയിൽ താങ്കളുടെ സെഷനോ സജ്ജീകരണങ്ങളോ സേവ് ചെയ്യപ്പെടുകയില്ല. ചില ബ്രൗസറുകളിൽ ഈതർപാഡ് ഐഫ്രെയിമിന്റെ കൂടെ ഉൾപ്പെടുത്തിയത്കൊണ്ടാവാം ഈ പ്രശ്നം. പാരന്റ് ഐഫ്രെയിമിന്റെ അതെ ഡൊമെയ്‌നിൽ/ഉപഡൊമെയ്‌നിൽ തന്നെയാണ് ഈതർപാഡ് ഉള്ളത് എന്ന കാര്യം ഉറപ്പ് വരുത്തുക.",
"pad.passwordRequired": "ഈ പാഡ് ഉപയോഗിക്കുന്നതിനായി ഒരു രഹസ്യവാക്ക് നൽകേണ്ടതാണ്", "pad.passwordRequired": "ഈ പാഡ് ഉപയോഗിക്കുന്നതിനായി ഒരു രഹസ്യവാക്ക് നൽകേണ്ടതാണ്",
"pad.permissionDenied": "ഈ പാഡ് കാണുവാൻ താങ്കൾക്ക് അനുമതിയില്ല", "pad.permissionDenied": "ഈ പാഡ് കാണുവാൻ താങ്കൾക്ക് അനുമതിയില്ല",
"pad.wrongPassword": "താങ്കൾ നല്കിയ രഹസ്യവാക്ക് തെറ്റായിരുന്നു", "pad.wrongPassword": "താങ്കൾ നല്കിയ രഹസ്യവാക്ക് തെറ്റായിരുന്നു",
@ -58,7 +58,7 @@
"pad.importExport.exportword": "മൈക്രോസോഫ്റ്റ് വേഡ്", "pad.importExport.exportword": "മൈക്രോസോഫ്റ്റ് വേഡ്",
"pad.importExport.exportpdf": "പി.ഡി.എഫ്.", "pad.importExport.exportpdf": "പി.ഡി.എഫ്.",
"pad.importExport.exportopen": "ഒ.ഡി.എഫ്. (ഓപ്പൺ ഡോക്യുമെന്റ് ഫോർമാറ്റ്)", "pad.importExport.exportopen": "ഒ.ഡി.എഫ്. (ഓപ്പൺ ഡോക്യുമെന്റ് ഫോർമാറ്റ്)",
"pad.importExport.abiword.innerHTML": "പ്ലെയിൻ ടെക്സ്റ്റോ എച്ച്.റ്റി.എം.എൽ. തരമോ മാത്രമേ താങ്കൾക്ക് ഇറക്കുമതി ചെയ്യാനാവൂ. കൂടുതൽ വിപുലീകൃത ഇറക്കുമതി സൗകര്യങ്ങൾക്കായി ദയവായി <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-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\">അബിവേഡ് അല്ലെങ്കിൽ ലിബർഓഫീസ് ഇൻസ്റ്റോൾ ചെയ്യുക</a>.",
"pad.modals.connected": "ബന്ധിപ്പിച്ചിരിക്കുന്നു.", "pad.modals.connected": "ബന്ധിപ്പിച്ചിരിക്കുന്നു.",
"pad.modals.reconnecting": "താങ്കളുടെ പാഡിലേയ്ക്ക് വീണ്ടും ബന്ധിപ്പിക്കുന്നു...", "pad.modals.reconnecting": "താങ്കളുടെ പാഡിലേയ്ക്ക് വീണ്ടും ബന്ധിപ്പിക്കുന്നു...",
"pad.modals.forcereconnect": "എന്തായാലും ബന്ധിപ്പിക്കുക", "pad.modals.forcereconnect": "എന്തായാലും ബന്ധിപ്പിക്കുക",
@ -125,7 +125,7 @@
"pad.userlist.guest": "അതിഥി", "pad.userlist.guest": "അതിഥി",
"pad.userlist.deny": "നിരസിക്കുക", "pad.userlist.deny": "നിരസിക്കുക",
"pad.userlist.approve": "അംഗീകരിക്കുക", "pad.userlist.approve": "അംഗീകരിക്കുക",
"pad.editbar.clearcolors": "ഡോക്യുമെന്റിൽ രചയിതാക്കളെ സൂചിപ്പിക്കാനായി നൽകിയിട്ടുള്ള നിറങ്ങൾ ഒഴിവാക്കട്ടെ?", "pad.editbar.clearcolors": "ഡോക്യുമെന്റിൽ രചയിതാക്കളെ സൂചിപ്പിക്കാനായി നൽകിയിട്ടുള്ള നിറങ്ങൾ ഒഴിവാക്കട്ടെ? ഈ തിരുത്തൽ പഴയപടി ആക്കുവാൻ സാധിക്കില്ല",
"pad.impexp.importbutton": "ഇറക്കുമതി ചെയ്യുക", "pad.impexp.importbutton": "ഇറക്കുമതി ചെയ്യുക",
"pad.impexp.importing": "ഇറക്കുമതി ചെയ്യുന്നു...", "pad.impexp.importing": "ഇറക്കുമതി ചെയ്യുന്നു...",
"pad.impexp.confirmimport": "ഒരു പ്രമാണം ഇറക്കുമതി ചെയ്യുന്നത് നിലവിലുള്ള എഴുത്തുകൾ നഷ്ടപ്പെടാനിടയാക്കും, തുടരണമെന്ന് ഉറപ്പാണോ?", "pad.impexp.confirmimport": "ഒരു പ്രമാണം ഇറക്കുമതി ചെയ്യുന്നത് നിലവിലുള്ള എഴുത്തുകൾ നഷ്ടപ്പെടാനിടയാക്കും, തുടരണമെന്ന് ഉറപ്പാണോ?",

View file

@ -18,7 +18,7 @@
"pad.colorpicker.cancel": "Moxitiniz", "pad.colorpicker.cancel": "Moxitiniz",
"pad.settings.padSettings": "Pad Ītlatlālīliz", "pad.settings.padSettings": "Pad Ītlatlālīliz",
"pad.settings.myView": "Notlachiyaliz", "pad.settings.myView": "Notlachiyaliz",
"pad.settings.language": "Tlahtōlli:", "pad.settings.language": "Tlahtolli:",
"pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML", "pad.importExport.exporthtml": "HTML",
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",

View file

@ -5,11 +5,13 @@
"Cocu", "Cocu",
"Jon Harald Søby", "Jon Harald Søby",
"Laaknor", "Laaknor",
"Orjanmen",
"SuperPotato" "SuperPotato"
] ]
}, },
"index.newPad": "Ny Pad", "index.newPad": "Ny pad",
"index.createOpenPad": "eller opprette/åpne en ny Pad med dette navnet:", "index.createOpenPad": "eller opprett/åpne en pad med dette navnet:",
"index.openPad": "åpne en eksisterende Pad med følgende navn:",
"pad.toolbar.bold.title": "Fet (Ctrl+B)", "pad.toolbar.bold.title": "Fet (Ctrl+B)",
"pad.toolbar.italic.title": "Kursiv (Ctrl+I)", "pad.toolbar.italic.title": "Kursiv (Ctrl+I)",
"pad.toolbar.underline.title": "Understreking (Ctrl+U)", "pad.toolbar.underline.title": "Understreking (Ctrl+U)",
@ -19,35 +21,37 @@
"pad.toolbar.indent.title": "Innrykk (TAB)", "pad.toolbar.indent.title": "Innrykk (TAB)",
"pad.toolbar.unindent.title": "Rykk ut (Shift+TAB)", "pad.toolbar.unindent.title": "Rykk ut (Shift+TAB)",
"pad.toolbar.undo.title": "Angre (Ctrl+Z)", "pad.toolbar.undo.title": "Angre (Ctrl+Z)",
"pad.toolbar.redo.title": "Gjør omigjen (Ctrl+Y)", "pad.toolbar.redo.title": "Gjør om igjen (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Fjern forfatterfarger (Ctrl+Shift+C)", "pad.toolbar.clearAuthorship.title": "Fjern forfatterfarger (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Importer/eksporter fra/til forskjellige filformater", "pad.toolbar.import_export.title": "Importer/eksporter fra/til ulike filformat",
"pad.toolbar.timeslider.title": "Tidslinje", "pad.toolbar.timeslider.title": "Tidslinje",
"pad.toolbar.savedRevision.title": "Lagre revisjoner", "pad.toolbar.savedRevision.title": "Lagre revisjon",
"pad.toolbar.settings.title": "Innstillinger", "pad.toolbar.settings.title": "Innstillinger",
"pad.toolbar.embed.title": "Del og sett inn denne Paden", "pad.toolbar.embed.title": "Del og sett inn denne pad-en",
"pad.toolbar.showusers.title": "Vis brukerne av denne Paden", "pad.toolbar.showusers.title": "Vis brukerne av denne pad-en",
"pad.colorpicker.save": "Lagre", "pad.colorpicker.save": "Lagre",
"pad.colorpicker.cancel": "Avbryt", "pad.colorpicker.cancel": "Avbryt",
"pad.loading": "Laster...", "pad.loading": "Laster",
"pad.noCookie": "Kunne ikke finne informasjonskapselen. Vennligst tillat informasjonskapsler (cookies) i din webleser!", "pad.noCookie": "Kunne ikke finne informasjonskapselen. Vennligst tillat informasjonskapsler (cookies) i din nettleser! Informasjonskapsler brukes til å lagre innstillinger o.l. Om feilen gjentar seg, kan det skyldes feil i nettsidens bruk av iFrame.",
"pad.passwordRequired": "Du trenger et passord for å få tilgang til denne Paden", "pad.passwordRequired": "Pad-en er låst med et passord",
"pad.permissionDenied": "Du har ikke tilgang til denne Paden", "pad.permissionDenied": "Du har ikke tilgang til denne pad-en",
"pad.wrongPassword": "Feil passord", "pad.wrongPassword": "Feil passord",
"pad.settings.padSettings": "Padinnstillinger", "pad.settings.padSettings": "Padinnstillinger",
"pad.settings.myView": "Min Visning", "pad.settings.myView": "Min visning",
"pad.settings.stickychat": "Chat alltid synlig", "pad.settings.stickychat": "Chat alltid synlig",
"pad.settings.chatandusers": "Vis chat og brukere", "pad.settings.chatandusers": "Vis chat og brukere",
"pad.settings.colorcheck": "Forfatterfarger", "pad.settings.colorcheck": "Forfatterfarger",
"pad.settings.linenocheck": "Linjenummer", "pad.settings.linenocheck": "Linjenummer",
"pad.settings.rtlcheck": "Les innhold fra høyre til venstre?", "pad.settings.rtlcheck": "Les innhold fra høyre til venstre",
"pad.settings.fontType": "Skrifttype:", "pad.settings.fontType": "Skrifttype:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Språk:", "pad.settings.language": "Språk:",
"pad.settings.about": "Om",
"pad.settings.poweredBy": "Drives av",
"pad.importExport.import_export": "Importer/eksporter", "pad.importExport.import_export": "Importer/eksporter",
"pad.importExport.import": "Last opp tekstfil eller dokument", "pad.importExport.import": "Last opp tekstfil eller dokument",
"pad.importExport.importSuccessful": "Vellykket!", "pad.importExport.importSuccessful": "Vellykket!",
"pad.importExport.export": "Eksporter blokken som:", "pad.importExport.export": "Eksporter som:",
"pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML", "pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Ren tekst", "pad.importExport.exportplain": "Ren tekst",
@ -56,32 +60,32 @@
"pad.importExport.exportopen": "ODF (Open Document Format)", "pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Du kan bare importere fra ren tekst eller HTML-formater. For mer avanserte importfunksjoner, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">installer AbiWord eller LibreOffice</a>.", "pad.importExport.abiword.innerHTML": "Du kan bare importere fra ren tekst eller HTML-formater. For mer avanserte importfunksjoner, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">installer AbiWord eller LibreOffice</a>.",
"pad.modals.connected": "Tilkoblet.", "pad.modals.connected": "Tilkoblet.",
"pad.modals.reconnecting": "Kobler til din blokk på nytt...", "pad.modals.reconnecting": "Kobler til pad-en på nytt …",
"pad.modals.forcereconnect": "Tving gjenoppkobling", "pad.modals.forcereconnect": "Tving gjenoppkobling",
"pad.modals.reconnecttimer": "Prøver å koble til igjen", "pad.modals.reconnecttimer": "Prøver å koble til på nytt",
"pad.modals.cancel": "Avbryt", "pad.modals.cancel": "Avbryt",
"pad.modals.userdup": "Åpnet i nytt vindu", "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.explanation": "Denne pad-en ser ut til å være åpnet i flere vindu/faner i nettleseren din.",
"pad.modals.userdup.advice": "Koble til igjen for å bruke dette vinduet i stedenfor.", "pad.modals.userdup.advice": "Koble til igjen for å redigere fra dette vinduet.",
"pad.modals.unauth": "Ikke tillatt", "pad.modals.unauth": "Ikke tillatt",
"pad.modals.unauth.explanation": "Dine rettigheter har blitt endret mens du så på denne siden. Prøv å koble til på nytt", "pad.modals.unauth.explanation": "Dine rettigheter har blitt endret mens du så på denne siden. Prøv å koble til på nytt",
"pad.modals.looping.explanation": "Det er kommunikasjonsproblemer med synkroniseringsserveren.", "pad.modals.looping.explanation": "Det er problemer med synkroniseringen av pad-en.",
"pad.modals.looping.cause": "Kanskje du koblet til en inkompatibel brannmur eller mellomtjener", "pad.modals.looping.cause": "Kanskje du koblet til en inkompatibel brannmur eller mellomtjener",
"pad.modals.initsocketfail": "Serveren er utilgjengelig", "pad.modals.initsocketfail": "Serveren er utilgjengelig",
"pad.modals.initsocketfail.explanation": "Kunne ikke koble til synkroniseringsserveren.", "pad.modals.initsocketfail.explanation": "Kunne ikke koble til synkroniseringsserveren.",
"pad.modals.initsocketfail.cause": "Dette er sannsynligvis på grunn av et problem med nettleseren eller din internettoppkobling", "pad.modals.initsocketfail.cause": "Dette skyldes sannsynligvis et problem med internettoppkoblingen, eller nettleseren din.",
"pad.modals.slowcommit.explanation": "Serveren svarer ikke.", "pad.modals.slowcommit.explanation": "Serveren svarer ikke.",
"pad.modals.slowcommit.cause": "Dette kan være et problem med nettverkstilkoblingen", "pad.modals.slowcommit.cause": "Dette skyldes nettverksoppkoblingen din.",
"pad.modals.badChangeset.explanation": "En redigering som du gjorde ble klassifisert som ulovlig av synkroniseringsserveren.", "pad.modals.badChangeset.explanation": "En redigering som du gjorde ble klassifisert som ugyldig av synkroniseringsserveren.",
"pad.modals.badChangeset.cause": "Dette kan komme av feil serverkonfigurasjon eller en annen uventet adferd. Vennligst kontakt serviceadministratoren hvis du anser dette å være feil. Prøv å gjenopprette forbindelsen for å fortsette med redigeringen.", "pad.modals.badChangeset.cause": "Dette kan komme av feil serverkonfigurasjon eller en annen uventet adferd. Vennligst kontakt serviceadministratoren hvis du anser dette å være feil. Prøv å gjenopprette forbindelsen for å fortsette med redigeringen.",
"pad.modals.corruptPad.explanation": "Blokken du forsøker å få tilgang til er skadet.", "pad.modals.corruptPad.explanation": "Pad-en du forsøker å få tilgang til, fungerer ikke.",
"pad.modals.corruptPad.cause": "Dette kan komme av feil serverkonfigurasjon eller en annen uventet adferd. Vennligst kontakt serviceadministratoren hvis du anser dette å være feil.", "pad.modals.corruptPad.cause": "Dette kan komme av feil serverkonfigurasjon eller en annen uventet adferd. Vennligst kontakt serviceadministratoren hvis du anser dette å være feil.",
"pad.modals.deleted": "Slettet.", "pad.modals.deleted": "Slettet.",
"pad.modals.deleted.explanation": "Denne blokken har blitt fjernet", "pad.modals.deleted.explanation": "Denne pad-en har blitt fjernet.",
"pad.modals.disconnected": "Du har blitt frakoblet.", "pad.modals.disconnected": "Du har blitt frakoblet.",
"pad.modals.disconnected.explanation": "Mistet tilkobling til serveren.", "pad.modals.disconnected.explanation": "Ingen tilkobling til serveren.",
"pad.modals.disconnected.cause": "Serveren kan være utilgjengelig. Vennligst si i fra til oss hvis dette fortsetter å skje.", "pad.modals.disconnected.cause": "Serveren kan være utilgjengelig. Vennligst gi beskjed dersom dette gjentar seg.",
"pad.share": "Del denne blokken", "pad.share": "Del denne pad-en",
"pad.share.readonly": "Skrivebeskyttet", "pad.share.readonly": "Skrivebeskyttet",
"pad.share.link": "Lenke", "pad.share.link": "Lenke",
"pad.share.emebdcode": "URL for innbygging", "pad.share.emebdcode": "URL for innbygging",
@ -90,17 +94,17 @@
"pad.chat.loadmessages": "Last flere beskjeder", "pad.chat.loadmessages": "Last flere beskjeder",
"pad.chat.stick.title": "Fest chatten til skjermen", "pad.chat.stick.title": "Fest chatten til skjermen",
"pad.chat.writeMessage.placeholder": "Skriv beskjeden din her", "pad.chat.writeMessage.placeholder": "Skriv beskjeden din her",
"timeslider.pageTitle": "{{appTitle}} Tidslinje", "timeslider.pageTitle": "{{appTitle}}-tidslinje",
"timeslider.toolbar.returnbutton": "Gå tilbake til blokk", "timeslider.toolbar.returnbutton": "Gå tilbake til pad-en",
"timeslider.toolbar.authors": "Forfattere:", "timeslider.toolbar.authors": "Forfattere:",
"timeslider.toolbar.authorsList": "Ingen forfattere", "timeslider.toolbar.authorsList": "Ingen forfattere",
"timeslider.toolbar.exportlink.title": "Eksporter", "timeslider.toolbar.exportlink.title": "Eksporter",
"timeslider.exportCurrent": "Eksporter nåværende versjon som:", "timeslider.exportCurrent": "Eksporter nåværende versjon som:",
"timeslider.version": "Versjon {{version}}", "timeslider.version": "Versjon {{version}}",
"timeslider.saved": "Lagret {{day}}. {{month}} {{year}}", "timeslider.saved": "Lagret {{day}}. {{month}} {{year}}",
"timeslider.playPause": "Spill av/Pause blokkinnholdet", "timeslider.playPause": "Spill av/Pause pad-innholdet",
"timeslider.backRevision": "Gå tilbake en revisjon i denne blokken", "timeslider.backRevision": "Gå tilbake en revisjon i denne pad-en",
"timeslider.forwardRevision": "Gå fremover en revisjon i denne blokken", "timeslider.forwardRevision": "Gå fremover en revisjon i denne pad-en",
"timeslider.dateformat": "{{day}}. {{month}} {{year}} {{hours}}:{{minutes}}:{{seconds}}", "timeslider.dateformat": "{{day}}. {{month}} {{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "januar", "timeslider.month.january": "januar",
"timeslider.month.february": "februar", "timeslider.month.february": "februar",
@ -114,7 +118,7 @@
"timeslider.month.october": "oktober", "timeslider.month.october": "oktober",
"timeslider.month.november": "november", "timeslider.month.november": "november",
"timeslider.month.december": "desember", "timeslider.month.december": "desember",
"timeslider.unnamedauthors": "{{num}} navnløse {[plural(num) one: forfatter, other: forfattere ]}", "timeslider.unnamedauthors": "{{num}} {[plural(num) one: navnløs forfatter, other: navnløse forfattere ]}",
"pad.savedrevs.marked": "Denne revisjonen er nå markert som en lagret revisjon", "pad.savedrevs.marked": "Denne revisjonen er nå markert som en lagret revisjon",
"pad.savedrevs.timeslider": "Du kan se lagrede revisjoner med tidslinjen", "pad.savedrevs.timeslider": "Du kan se lagrede revisjoner med tidslinjen",
"pad.userlist.entername": "Skriv inn ditt navn", "pad.userlist.entername": "Skriv inn ditt navn",
@ -124,14 +128,14 @@
"pad.userlist.approve": "Godkjenn", "pad.userlist.approve": "Godkjenn",
"pad.editbar.clearcolors": "Fjern forfatterfarger på hele dokumentet? Dette kan ikke angres", "pad.editbar.clearcolors": "Fjern forfatterfarger på hele dokumentet? Dette kan ikke angres",
"pad.impexp.importbutton": "Importer nå", "pad.impexp.importbutton": "Importer nå",
"pad.impexp.importing": "Importerer...", "pad.impexp.importing": "Importerer",
"pad.impexp.confirmimport": "Importering av en fil vil overskrive den nåværende teksten på blokken. Er du sikker på at du vil fortsette?", "pad.impexp.confirmimport": "Importering av en fil vil overskrive den nåværende teksten på blokken. Er du sikker på at du vil fortsette?",
"pad.impexp.convertFailed": "Vi greide ikke å importere denne filen. Bruk et annet dokumentformat eller kopier og lim inn teksten manuelt", "pad.impexp.convertFailed": "Vi greide ikke å importere denne filen. Bruk et annet dokumentformat eller kopier og lim inn teksten manuelt",
"pad.impexp.padHasData": "Vi kunne ikke importere denne filen fordi blokken allerede hadde endringer. Importer til en ny blokk.", "pad.impexp.padHasData": "Vi kunne ikke importere denne filen fordi blokken allerede hadde endringer. Importer til en ny blokk.",
"pad.impexp.uploadFailed": "Opplastning feilet. Prøv igjen", "pad.impexp.uploadFailed": "Opplastning feilet. Prøv igjen",
"pad.impexp.importfailed": "Import feilet", "pad.impexp.importfailed": "Import feilet",
"pad.impexp.copypaste": "Vennligst kopier og lim inn", "pad.impexp.copypaste": "Vennligst kopier og lim inn",
"pad.impexp.exportdisabled": "Eksporterer som {{type}} er deaktivert. Vennligst kontakt din systemadministrator for detaljer.", "pad.impexp.exportdisabled": "Eksportering som {{type}} er deaktivert. Vennligst kontakt systemadministratoren din for detaljer.",
"pad.impexp.maxFileSize": "Filen er for stor. Kontakt systemansvarlig for å øke filstørrelse for import", "pad.impexp.maxFileSize": "Filen er for stor. Kontakt systemansvarlig for å øke filstørrelse for import",
"pad.impexp.permission": "Import er deaktivert fordi du aldri har bidratt til denne padden. Vennligst bidra minst en gang før du importerer" "pad.impexp.permission": "Import er deaktivert fordi du aldri har bidratt til denne padden. Vennligst bidra minst en gang før du importerer"
} }

View file

@ -1,6 +1,7 @@
{ {
"@metadata": { "@metadata": {
"authors": [ "authors": [
"Nirajan pant",
"Nirjal stha", "Nirjal stha",
"राम प्रसाद जोशी", "राम प्रसाद जोशी",
"सरोज कुमार ढकाल", "सरोज कुमार ढकाल",
@ -41,6 +42,8 @@
"pad.settings.fontType": "लिपि प्रकार:", "pad.settings.fontType": "लिपि प्रकार:",
"pad.settings.fontType.normal": "सामान्य", "pad.settings.fontType.normal": "सामान्य",
"pad.settings.language": "भाषा:", "pad.settings.language": "भाषा:",
"pad.settings.about": "बारेमा",
"pad.settings.poweredBy": "प्रवर्धक",
"pad.importExport.import_export": "आयात/निर्यात", "pad.importExport.import_export": "आयात/निर्यात",
"pad.importExport.import": "कुनै पनि पाठ रहेको फाइल या कागजात अपलोड गर्नुहोस्", "pad.importExport.import": "कुनै पनि पाठ रहेको फाइल या कागजात अपलोड गर्नुहोस्",
"pad.importExport.importSuccessful": "सफल भयो!", "pad.importExport.importSuccessful": "सफल भयो!",

View file

@ -1,6 +1,7 @@
{ {
"@metadata": { "@metadata": {
"authors": [ "authors": [
"Dutchy45",
"Klaas van Buiten", "Klaas van Buiten",
"KlaasZ4usV", "KlaasZ4usV",
"Macofe", "Macofe",
@ -49,6 +50,7 @@
"pad.settings.fontType": "Lettertype:", "pad.settings.fontType": "Lettertype:",
"pad.settings.fontType.normal": "Normaal", "pad.settings.fontType.normal": "Normaal",
"pad.settings.language": "Taal:", "pad.settings.language": "Taal:",
"pad.settings.about": "Over",
"pad.importExport.import_export": "Importeren/exporteren", "pad.importExport.import_export": "Importeren/exporteren",
"pad.importExport.import": "Tekstbestand of document uploaden", "pad.importExport.import": "Tekstbestand of document uploaden",
"pad.importExport.importSuccessful": "Afgerond", "pad.importExport.importSuccessful": "Afgerond",

View file

@ -15,6 +15,7 @@
}, },
"index.newPad": "Nowy dokument", "index.newPad": "Nowy dokument",
"index.createOpenPad": "lub stwórz/otwórz dokument o nazwie:", "index.createOpenPad": "lub stwórz/otwórz dokument o nazwie:",
"index.openPad": "otwórz istniejący dokument o nazwie:",
"pad.toolbar.bold.title": "Pogrubienie (Ctrl-B)", "pad.toolbar.bold.title": "Pogrubienie (Ctrl-B)",
"pad.toolbar.italic.title": "Kursywa (Ctrl-I)", "pad.toolbar.italic.title": "Kursywa (Ctrl-I)",
"pad.toolbar.underline.title": "Podkreślenie (Ctrl-U)", "pad.toolbar.underline.title": "Podkreślenie (Ctrl-U)",
@ -35,7 +36,7 @@
"pad.colorpicker.save": "Zapisz", "pad.colorpicker.save": "Zapisz",
"pad.colorpicker.cancel": "Anuluj", "pad.colorpicker.cancel": "Anuluj",
"pad.loading": "Ładowanie...", "pad.loading": "Ładowanie...",
"pad.noCookie": "Nie znaleziono pliku cookie. Proszę zezwolić na pliki cookie w przeglądarce!", "pad.noCookie": "Nie można znaleźć pliku cookie. Proszę zezwolić na pliki cookie w przeglądarce! Twoja sesja i ustawienia nie zostaną zapisane między wizytami. Może to wynikać z włączenia Etherpad do ramki iFrame w niektórych przeglądarkach. Upewnij się, że Etherpad jest w tej samej subdomenie/domenie, co nadrzędna ramka iFrame",
"pad.passwordRequired": "Musisz podać hasło aby uzyskać dostęp do tego dokumentu", "pad.passwordRequired": "Musisz podać hasło aby uzyskać dostęp do tego dokumentu",
"pad.permissionDenied": "Nie masz uprawnień dostępu do tego dokumentu", "pad.permissionDenied": "Nie masz uprawnień dostępu do tego dokumentu",
"pad.wrongPassword": "Nieprawidłowe hasło", "pad.wrongPassword": "Nieprawidłowe hasło",
@ -49,6 +50,7 @@
"pad.settings.fontType": "Rodzaj czcionki:", "pad.settings.fontType": "Rodzaj czcionki:",
"pad.settings.fontType.normal": "Normalna", "pad.settings.fontType.normal": "Normalna",
"pad.settings.language": "Język:", "pad.settings.language": "Język:",
"pad.settings.about": "O aplikacji",
"pad.importExport.import_export": "Import/eksport", "pad.importExport.import_export": "Import/eksport",
"pad.importExport.import": "Prześlij dowolny plik tekstowy lub dokument", "pad.importExport.import": "Prześlij dowolny plik tekstowy lub dokument",
"pad.importExport.importSuccessful": "Sukces!", "pad.importExport.importSuccessful": "Sukces!",
@ -59,7 +61,7 @@
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)", "pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Możesz importować pliki tylko w formacie zwykłego tekstu lub HTML. Aby umożliwić bardziej zaawansowane funkcje importu, <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\">zainstaluj AbiWord</a>.", "pad.importExport.abiword.innerHTML": "Możesz importować pliki tylko w formacie zwykłego tekstu lub HTML. Aby umożliwić bardziej zaawansowane funkcje importu, <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\">zainstaluj AbiWord lub LibreOffice</a>.",
"pad.modals.connected": "Połączony.", "pad.modals.connected": "Połączony.",
"pad.modals.reconnecting": "Ponowne łączenie z dokumentem...", "pad.modals.reconnecting": "Ponowne łączenie z dokumentem...",
"pad.modals.forcereconnect": "Wymuś ponowne połączenie", "pad.modals.forcereconnect": "Wymuś ponowne połączenie",
@ -127,7 +129,7 @@
"pad.userlist.guest": "Gość", "pad.userlist.guest": "Gość",
"pad.userlist.deny": "Zabroń", "pad.userlist.deny": "Zabroń",
"pad.userlist.approve": "Zezwól", "pad.userlist.approve": "Zezwól",
"pad.editbar.clearcolors": "Wyczyścić kolory autorstwa w całym dokumencie?", "pad.editbar.clearcolors": "Wyczyścić kolory autorstwa w całym dokumencie? Nie można będzie tego cofnąć!",
"pad.impexp.importbutton": "Importuj teraz", "pad.impexp.importbutton": "Importuj teraz",
"pad.impexp.importing": "Importowanie...", "pad.impexp.importing": "Importowanie...",
"pad.impexp.confirmimport": "Importowanie pliku spowoduje zastąpienie bieżącego tekstu. Czy na pewno chcesz kontynuować?", "pad.impexp.confirmimport": "Importowanie pliku spowoduje zastąpienie bieżącego tekstu. Czy na pewno chcesz kontynuować?",
@ -136,5 +138,7 @@
"pad.impexp.uploadFailed": "Przesyłanie nie powiodło się, proszę spróbować jeszcze raz", "pad.impexp.uploadFailed": "Przesyłanie nie powiodło się, proszę spróbować jeszcze raz",
"pad.impexp.importfailed": "Importowanie nie powiodło się", "pad.impexp.importfailed": "Importowanie nie powiodło się",
"pad.impexp.copypaste": "Proszę skopiować i wkleić", "pad.impexp.copypaste": "Proszę skopiować i wkleić",
"pad.impexp.exportdisabled": "Eksport do formatu {{type}} jest wyłączony. Proszę skontaktować się z administratorem aby uzyskać więcej szczegółów." "pad.impexp.exportdisabled": "Eksport do formatu {{type}} jest wyłączony. Proszę skontaktować się z administratorem aby uzyskać więcej szczegółów.",
"pad.impexp.maxFileSize": "Plik jest zbyt duży. Skontaktuj się z administratorem aby zwiększył maksymalny dopuszczalny rozmiar importowanych plików",
"pad.impexp.permission": "Importowanie jest zablokowane, ponieważ nie edytowałeś jeszcze tego dokumentu. Wykonaj przynajmniej jedną zmianę zanim zaczniesz importować"
} }

View file

@ -6,6 +6,7 @@
}, },
"index.newPad": "Feuj neuv", "index.newPad": "Feuj neuv",
"index.createOpenPad": "o creé/duverté un feuj antitolà:", "index.createOpenPad": "o creé/duverté un feuj antitolà:",
"index.openPad": "duverté un Pad esistent con ël nòm:",
"pad.toolbar.bold.title": "Grassèt (Ctrl+B)", "pad.toolbar.bold.title": "Grassèt (Ctrl+B)",
"pad.toolbar.italic.title": "Corsiv (Ctrl+I)", "pad.toolbar.italic.title": "Corsiv (Ctrl+I)",
"pad.toolbar.underline.title": "Sotlignà (Ctrl+U)", "pad.toolbar.underline.title": "Sotlignà (Ctrl+U)",
@ -26,7 +27,7 @@
"pad.colorpicker.save": "Argistré", "pad.colorpicker.save": "Argistré",
"pad.colorpicker.cancel": "Anulé", "pad.colorpicker.cancel": "Anulé",
"pad.loading": "Antramentr ch'as caria…", "pad.loading": "Antramentr ch'as caria…",
"pad.noCookie": "Ël bëscotin a l'é nen ëstàit trovà. Për piasì, ch'a autorisa ij bëscotin su sò navigador!", "pad.noCookie": "Ël bëscotin a l'é nen ëstàit trovà. Për piasì, ch'a autorisa ij bëscotin su sò navigador! Soa session e sò paràmeter a saran pa argistrà antra na vìsita e l'àutra. Sòn a peul esse dovù al fàit che Etherpad a l'é contnù an n'iFrame an chèich navigador. Ch'a contròla che Etherpad resta ant l'istess sot-domini/domini ëd sò ce iFrame",
"pad.passwordRequired": "A l'ha da manca ëd na ciav për acede a cost feuj-sì", "pad.passwordRequired": "A l'ha da manca ëd na ciav për acede a cost feuj-sì",
"pad.permissionDenied": "A l'ha nen ël përmess d'acede a 's feuj-sì", "pad.permissionDenied": "A l'ha nen ël përmess d'acede a 's feuj-sì",
"pad.wrongPassword": "Soa ciav a l'era nen giusta", "pad.wrongPassword": "Soa ciav a l'era nen giusta",
@ -39,6 +40,8 @@
"pad.settings.rtlcheck": "Ël contnù, dev-lo esse lesù da drita a snistra?", "pad.settings.rtlcheck": "Ël contnù, dev-lo esse lesù da drita a snistra?",
"pad.settings.fontType": "Sòrt ëd caràter:", "pad.settings.fontType": "Sòrt ëd caràter:",
"pad.settings.language": "Lenga:", "pad.settings.language": "Lenga:",
"pad.settings.about": "A propòsit",
"pad.settings.poweredBy": "Potensià da",
"pad.importExport.import_export": "Amporté/Esporté", "pad.importExport.import_export": "Amporté/Esporté",
"pad.importExport.import": "Carié n'archivi o document ëd test", "pad.importExport.import": "Carié n'archivi o document ëd test",
"pad.importExport.importSuccessful": "Bele fàit!", "pad.importExport.importSuccessful": "Bele fàit!",
@ -49,7 +52,7 @@
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)", "pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "A peul mach amporté dij formà ëd test sempi o HTML. Për dle fonsionalità d'amportassion pi avansà, ch'a <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">anstala AbiWord</a>.", "pad.importExport.abiword.innerHTML": "A peul mach amporté dij formà ëd test sempi o HTML. Për dle fonsionalità d'amportassion pi avansà, ch'a <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">anstala AbiWord o LibreOffice</a>.",
"pad.modals.connected": "Colegà.", "pad.modals.connected": "Colegà.",
"pad.modals.reconnecting": "Neuva conession a sò feuj...", "pad.modals.reconnecting": "Neuva conession a sò feuj...",
"pad.modals.forcereconnect": "Forsé la neuva conession", "pad.modals.forcereconnect": "Forsé la neuva conession",
@ -73,6 +76,8 @@
"pad.modals.corruptPad.cause": "Sòn a podrìa esse dovù a na configurassion ësbalià dël servent o a chèich àutr comportament nen ëspetà. Për piasì, ch'a contata l'aministrator dël servissi.", "pad.modals.corruptPad.cause": "Sòn a podrìa esse dovù a na configurassion ësbalià dël servent o a chèich àutr comportament nen ëspetà. Për piasì, ch'a contata l'aministrator dël servissi.",
"pad.modals.deleted": "Dëscancelà.", "pad.modals.deleted": "Dëscancelà.",
"pad.modals.deleted.explanation": "Ës feuj a l'é stàit eliminà.", "pad.modals.deleted.explanation": "Ës feuj a l'é stàit eliminà.",
"pad.modals.rateLimited": "Tass limità.",
"pad.modals.rateLimited.explanation": "A l'ha mandà tròpi mëssagi a 's blòch-sì, antlora a l'ha dëscolegalo.",
"pad.modals.disconnected": "A l'é stàit dëscolegà", "pad.modals.disconnected": "A l'é stàit dëscolegà",
"pad.modals.disconnected.explanation": "La conession al servent a l'é perdusse", "pad.modals.disconnected.explanation": "La conession al servent a l'é perdusse",
"pad.modals.disconnected.cause": "Ël servent a podrìa esse indisponìbil. Për piasì, ch'a anforma l'aministrator dël servissi si ël problema a persist.", "pad.modals.disconnected.cause": "Ël servent a podrìa esse indisponìbil. Për piasì, ch'a anforma l'aministrator dël servissi si ël problema a persist.",
@ -85,6 +90,7 @@
"pad.chat.loadmessages": "Carié pi 'd mëssagi", "pad.chat.loadmessages": "Carié pi 'd mëssagi",
"pad.chat.stick.title": "Taché la ciaciarada an slë scren", "pad.chat.stick.title": "Taché la ciaciarada an slë scren",
"pad.chat.writeMessage.placeholder": "Ch'a scriva sò mëssage ambelessì", "pad.chat.writeMessage.placeholder": "Ch'a scriva sò mëssage ambelessì",
"timeslider.followContents": "Steje dapress a j'agiornament ëd contnù dël blòch",
"timeslider.pageTitle": "Stòria dinàmica ëd {{appTitle}}", "timeslider.pageTitle": "Stòria dinàmica ëd {{appTitle}}",
"timeslider.toolbar.returnbutton": "Torné al feuj", "timeslider.toolbar.returnbutton": "Torné al feuj",
"timeslider.toolbar.authors": "Autor:", "timeslider.toolbar.authors": "Autor:",
@ -126,5 +132,7 @@
"pad.impexp.uploadFailed": "Ël cariament a l'ha falì, për piasì ch'a preuva torna", "pad.impexp.uploadFailed": "Ël cariament a l'ha falì, për piasì ch'a preuva torna",
"pad.impexp.importfailed": "Amportassion falìa", "pad.impexp.importfailed": "Amportassion falìa",
"pad.impexp.copypaste": "Për piasì, ch'a còpia e ancòla", "pad.impexp.copypaste": "Për piasì, ch'a còpia e ancòla",
"pad.impexp.exportdisabled": "L'esportassion an formà {{type}} a l'é disativà. Për piasì, ch'a contata sò aministrator ëd sistema për ij detaj." "pad.impexp.exportdisabled": "L'esportassion an formà {{type}} a l'é disativà. Për piasì, ch'a contata sò aministrator ëd sistema për ij detaj.",
"pad.impexp.maxFileSize": "Archivi tròp gròss. Ch'a contata sò aministrator ëd sit për sumenté la taja dj'archivi consentìa për j'amportassion",
"pad.impexp.permission": "L'amportassion a l'é disativà përchè chiel a l'ha pa mai contribuì a cost blòch-sì. Për piasì, ch'a contribuissa almanch na vira prima d'amporté"
} }

View file

@ -21,6 +21,7 @@
}, },
"index.newPad": "Nova Nota", "index.newPad": "Nova Nota",
"index.createOpenPad": "ou criar-abrir uma Nota com o nome:", "index.createOpenPad": "ou criar-abrir uma Nota com o nome:",
"index.openPad": "abra um bloco existente com o nome:",
"pad.toolbar.bold.title": "Negrito (Ctrl-B)", "pad.toolbar.bold.title": "Negrito (Ctrl-B)",
"pad.toolbar.italic.title": "Itálico (Ctrl-I)", "pad.toolbar.italic.title": "Itálico (Ctrl-I)",
"pad.toolbar.underline.title": "Sublinhado (Ctrl-U)", "pad.toolbar.underline.title": "Sublinhado (Ctrl-U)",
@ -41,7 +42,7 @@
"pad.colorpicker.save": "Salvar", "pad.colorpicker.save": "Salvar",
"pad.colorpicker.cancel": "Cancelar", "pad.colorpicker.cancel": "Cancelar",
"pad.loading": "Carregando...", "pad.loading": "Carregando...",
"pad.noCookie": "Cookie não foi encontrado. Por favor, habilite cookies no seu navegador!", "pad.noCookie": "Não foi possível encontrar o cookie. Por favor, permita cookies no seu navegador! Sua sessão e configurações não serão salvas entre as visitas. Isso pode ser devido ao fato de o Etherpad ser incluído em um iFrame em alguns navegadores. Verifique se o Etherpad está no mesmo subdomínio/domínio que o iFrame pai",
"pad.passwordRequired": "Você precisa de uma senha para acessar esta Nota", "pad.passwordRequired": "Você precisa de uma senha para acessar esta Nota",
"pad.permissionDenied": "Você não tem permissão para acessar esta Nota", "pad.permissionDenied": "Você não tem permissão para acessar esta Nota",
"pad.wrongPassword": "Senha incorreta", "pad.wrongPassword": "Senha incorreta",
@ -55,6 +56,8 @@
"pad.settings.fontType": "Tipo de fonte:", "pad.settings.fontType": "Tipo de fonte:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Idioma:", "pad.settings.language": "Idioma:",
"pad.settings.about": "Sobre",
"pad.settings.poweredBy": "Fornecido por",
"pad.importExport.import_export": "Importar/Exportar", "pad.importExport.import_export": "Importar/Exportar",
"pad.importExport.import": "Enviar um arquivo texto ou documento", "pad.importExport.import": "Enviar um arquivo texto ou documento",
"pad.importExport.importSuccessful": "Completo!", "pad.importExport.importSuccessful": "Completo!",
@ -89,6 +92,8 @@
"pad.modals.corruptPad.cause": "Isto pode ocorrer devido a uma configuração errada do servidor ou algum outro comportamento inesperado. Por favor contate o administrador.", "pad.modals.corruptPad.cause": "Isto pode ocorrer devido a uma configuração errada do servidor ou algum outro comportamento inesperado. Por favor contate o administrador.",
"pad.modals.deleted": "Excluído.", "pad.modals.deleted": "Excluído.",
"pad.modals.deleted.explanation": "Esta nota foi removida.", "pad.modals.deleted.explanation": "Esta nota foi removida.",
"pad.modals.rateLimited": "Limitado.",
"pad.modals.rateLimited.explanation": "Você enviou muitas mensagens para este pad por isso será desconectado.",
"pad.modals.disconnected": "Você foi desconectado.", "pad.modals.disconnected": "Você foi desconectado.",
"pad.modals.disconnected.explanation": "A conexão com o servidor foi perdida", "pad.modals.disconnected.explanation": "A conexão com o servidor foi perdida",
"pad.modals.disconnected.cause": "O servidor pode estar indisponível. Por favor, notifique o administrador caso isso continue.", "pad.modals.disconnected.cause": "O servidor pode estar indisponível. Por favor, notifique o administrador caso isso continue.",
@ -101,6 +106,7 @@
"pad.chat.loadmessages": "Carregar mais mensagens", "pad.chat.loadmessages": "Carregar mais mensagens",
"pad.chat.stick.title": "Cole o bate-papo na tela", "pad.chat.stick.title": "Cole o bate-papo na tela",
"pad.chat.writeMessage.placeholder": "Escreva sua mensagem aqui", "pad.chat.writeMessage.placeholder": "Escreva sua mensagem aqui",
"timeslider.followContents": "Siga as atualizações de conteúdo do pad",
"timeslider.pageTitle": "Linha do tempo de {{appTitle}}", "timeslider.pageTitle": "Linha do tempo de {{appTitle}}",
"timeslider.toolbar.returnbutton": "Retornar para a nota", "timeslider.toolbar.returnbutton": "Retornar para a nota",
"timeslider.toolbar.authors": "Autores:", "timeslider.toolbar.authors": "Autores:",

View file

@ -3,6 +3,7 @@
"authors": [ "authors": [
"Athena in Wonderland", "Athena in Wonderland",
"Cainamarques", "Cainamarques",
"GoEThe",
"Hamilton Abreu", "Hamilton Abreu",
"Imperadeiro98", "Imperadeiro98",
"Luckas", "Luckas",
@ -16,6 +17,7 @@
}, },
"index.newPad": "Nova Nota", "index.newPad": "Nova Nota",
"index.createOpenPad": "ou crie/abra uma nota com o nome:", "index.createOpenPad": "ou crie/abra uma nota com o nome:",
"index.openPad": "abrir uma «Nota» existente com o nome:",
"pad.toolbar.bold.title": "Negrito (Ctrl+B)", "pad.toolbar.bold.title": "Negrito (Ctrl+B)",
"pad.toolbar.italic.title": "Itálico (Ctrl+I)", "pad.toolbar.italic.title": "Itálico (Ctrl+I)",
"pad.toolbar.underline.title": "Sublinhado (Ctrl+U)", "pad.toolbar.underline.title": "Sublinhado (Ctrl+U)",
@ -36,7 +38,7 @@
"pad.colorpicker.save": "Gravar", "pad.colorpicker.save": "Gravar",
"pad.colorpicker.cancel": "Cancelar", "pad.colorpicker.cancel": "Cancelar",
"pad.loading": "A carregar…", "pad.loading": "A carregar…",
"pad.noCookie": "O cookie não foi encontrado. Por favor, ative os cookies no seu navegador!", "pad.noCookie": "Não foi possível encontrar o ''cookie''. Por favor, permita ''cookies'' no seu navegador! A sua sessão e as definições não foram guardadas entre as visitas. Isto poderá ter ocorrido porque Etherpad foi incluído numa iFrame em alguns «Navegadores». Por favor, certifique-se que Etherpad está no mesmo subdomínio / domínio que a iFrame fonte",
"pad.passwordRequired": "Precisa de uma palavra-passe para aceder a esta nota", "pad.passwordRequired": "Precisa de uma palavra-passe para aceder a esta nota",
"pad.permissionDenied": "Não tem permissão para aceder a esta nota", "pad.permissionDenied": "Não tem permissão para aceder a esta nota",
"pad.wrongPassword": "A sua palavra-passe estava errada", "pad.wrongPassword": "A sua palavra-passe estava errada",
@ -50,6 +52,8 @@
"pad.settings.fontType": "Tipo de letra:", "pad.settings.fontType": "Tipo de letra:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Língua:", "pad.settings.language": "Língua:",
"pad.settings.about": "Sobre",
"pad.settings.poweredBy": "Desenvolvido por",
"pad.importExport.import_export": "Importar/Exportar", "pad.importExport.import_export": "Importar/Exportar",
"pad.importExport.import": "Carregar qualquer ficheiro de texto ou documento", "pad.importExport.import": "Carregar qualquer ficheiro de texto ou documento",
"pad.importExport.importSuccessful": "Completo!", "pad.importExport.importSuccessful": "Completo!",
@ -60,7 +64,7 @@
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)", "pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Só pode importar texto sem formatação ou formatos HTML. Para funcionalidades de importação mais avançadas, por favor, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instale o AbiWord ou LibreOffice</a>.", "pad.importExport.abiword.innerHTML": "Só pode fazer importações de texto não formatado ou com formato HTML. Para funcionalidades de importação de texto mais avançadas, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instale AbiWord ou LibreOffice</a>, por favor.",
"pad.modals.connected": "Ligado.", "pad.modals.connected": "Ligado.",
"pad.modals.reconnecting": "A restabelecer ligação ao seu bloco…", "pad.modals.reconnecting": "A restabelecer ligação ao seu bloco…",
"pad.modals.forcereconnect": "Forçar restabelecimento de ligação", "pad.modals.forcereconnect": "Forçar restabelecimento de ligação",
@ -84,6 +88,8 @@
"pad.modals.corruptPad.cause": "Isto pode ocorrer devido a uma configuração errada do servidor ou algum outro comportamento inesperado. Por favor contacte o administrador.", "pad.modals.corruptPad.cause": "Isto pode ocorrer devido a uma configuração errada do servidor ou algum outro comportamento inesperado. Por favor contacte o administrador.",
"pad.modals.deleted": "Eliminado.", "pad.modals.deleted": "Eliminado.",
"pad.modals.deleted.explanation": "Esta nota foi removida.", "pad.modals.deleted.explanation": "Esta nota foi removida.",
"pad.modals.rateLimited": "Limitado.",
"pad.modals.rateLimited.explanation": "Enviou demasiadas mensagens para este pad, por isso foi desligado.",
"pad.modals.disconnected": "Você foi desligado.", "pad.modals.disconnected": "Você foi desligado.",
"pad.modals.disconnected.explanation": "A ligação ao servidor foi perdida", "pad.modals.disconnected.explanation": "A ligação ao servidor foi perdida",
"pad.modals.disconnected.cause": "O servidor pode estar indisponível. Por favor, notifique o administrador de serviço se isto continuar a acontecer.", "pad.modals.disconnected.cause": "O servidor pode estar indisponível. Por favor, notifique o administrador de serviço se isto continuar a acontecer.",
@ -96,6 +102,7 @@
"pad.chat.loadmessages": "Carregar mais mensagens", "pad.chat.loadmessages": "Carregar mais mensagens",
"pad.chat.stick.title": "Colar conversação no ecrã", "pad.chat.stick.title": "Colar conversação no ecrã",
"pad.chat.writeMessage.placeholder": "Escreva a sua mensagem aqui", "pad.chat.writeMessage.placeholder": "Escreva a sua mensagem aqui",
"timeslider.followContents": "Siga as atualizações do conteúdo do pad",
"timeslider.pageTitle": "Linha do tempo de {{appTitle}}", "timeslider.pageTitle": "Linha do tempo de {{appTitle}}",
"timeslider.toolbar.returnbutton": "Voltar à nota", "timeslider.toolbar.returnbutton": "Voltar à nota",
"timeslider.toolbar.authors": "Autores:", "timeslider.toolbar.authors": "Autores:",
@ -128,7 +135,7 @@
"pad.userlist.guest": "Convidado", "pad.userlist.guest": "Convidado",
"pad.userlist.deny": "Negar", "pad.userlist.deny": "Negar",
"pad.userlist.approve": "Aprovar", "pad.userlist.approve": "Aprovar",
"pad.editbar.clearcolors": "Limpar as cores de autoria em todo o documento? isto não pode ser anulado", "pad.editbar.clearcolors": "Limpar as cores de autoria do documento todo? Esta operação não pode ser desfeita",
"pad.impexp.importbutton": "Importar agora", "pad.impexp.importbutton": "Importar agora",
"pad.impexp.importing": "Importando...", "pad.impexp.importing": "Importando...",
"pad.impexp.confirmimport": "A importação de um ficheiro irá substituir o texto atual da nota. Tem certeza que deseja continuar?", "pad.impexp.confirmimport": "A importação de um ficheiro irá substituir o texto atual da nota. Tem certeza que deseja continuar?",
@ -138,6 +145,6 @@
"pad.impexp.importfailed": "A importação falhou", "pad.impexp.importfailed": "A importação falhou",
"pad.impexp.copypaste": "Copie e insira, por favor", "pad.impexp.copypaste": "Copie e insira, por favor",
"pad.impexp.exportdisabled": "A exportação no formato {{type}} está desativada. Por favor, contacte o administrador do sistema para mais informações.", "pad.impexp.exportdisabled": "A exportação no formato {{type}} está desativada. Por favor, contacte o administrador do sistema para mais informações.",
"pad.impexp.maxFileSize": "Ficheiro muito grande. Contacte o administrador do ''site'' para aumentar o tamanho do ficheiro permitido para importar", "pad.impexp.maxFileSize": "Ficheiro demasiado grande. Contacte o administrador do ''site'' para aumentar o tamanho máximo dos ficheiros importados",
"pad.impexp.permission": "A importação está desativada porque nunca contribuiu para este bloco. Por favor, contribua pelo menos uma vez antes de importar" "pad.impexp.permission": "A importação está desativada porque nunca contribuiu para esta nota. Contribua pelo menos uma vez antes de importar, por favor"
} }

View file

@ -5,7 +5,8 @@
"Mklehr", "Mklehr",
"Nemo bis", "Nemo bis",
"Shirayuki", "Shirayuki",
"Siebrand" "Siebrand",
"Tim.krieger"
] ]
}, },
"index.newPad": "Used as button text.\nA pad, in the context of Etherpad, is a notepad, something to write on.", "index.newPad": "Used as button text.\nA pad, in the context of Etherpad, is a notepad, something to write on.",
@ -106,7 +107,7 @@
"timeslider.month.december": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|December}}", "timeslider.month.december": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|December}}",
"timeslider.unnamedauthors": "See also:\n* {{msg-etherpadlite|Timeslider.unnamedauthor}}", "timeslider.unnamedauthors": "See also:\n* {{msg-etherpadlite|Timeslider.unnamedauthor}}",
"pad.savedrevs.marked": "more like bookmarked, or tagged/starred", "pad.savedrevs.marked": "more like bookmarked, or tagged/starred",
"pad.userlist.entername": "Used as placeholder for the \"Name\" input box in the upper right corner of the screen.", "pad.userlist.entername": "Used as placeholder for the \"Name\" input box in the upper right corner of the screen. It's important to keep it short: Long sentences aren't displayed.",
"pad.userlist.unnamed": "Displayed, if a user has not set a nick yet", "pad.userlist.unnamed": "Displayed, if a user has not set a nick yet",
"pad.userlist.guest": "Preceded by the link text which is labeled {{msg-etherpadlite|Pad.userlist.approve}}.\n{{Identical|Guest}}", "pad.userlist.guest": "Preceded by the link text which is labeled {{msg-etherpadlite|Pad.userlist.approve}}.\n{{Identical|Guest}}",
"pad.userlist.deny": "Used as link text.\n\nFollowed by the link which is labeled {{msg-etherpadlite|Pad.userlist.approve}}.", "pad.userlist.deny": "Used as link text.\n\nFollowed by the link which is labeled {{msg-etherpadlite|Pad.userlist.approve}}.",

View file

@ -1,8 +1,10 @@
{ {
"@metadata": { "@metadata": {
"authors": [ "authors": [
"Carcassonne93",
"Hedwig", "Hedwig",
"ImGelu", "ImGelu",
"MSClaudiu",
"Minisarm", "Minisarm",
"Strainu", "Strainu",
"Wintereu" "Wintereu"
@ -10,32 +12,41 @@
}, },
"index.newPad": "Pad nou", "index.newPad": "Pad nou",
"index.createOpenPad": "sau creează/deschide un Pad cu numele:", "index.createOpenPad": "sau creează/deschide un Pad cu numele:",
"index.openPad": "deschide un Pad existent cu numele:",
"pad.toolbar.bold.title": "Aldin (Ctrl + B)", "pad.toolbar.bold.title": "Aldin (Ctrl + B)",
"pad.toolbar.italic.title": "Cursiv (Ctrl + I)", "pad.toolbar.italic.title": "Cursiv (Ctrl + I)",
"pad.toolbar.underline.title": "Subliniază (Ctrl+U)", "pad.toolbar.underline.title": "Subliniază (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Taie (Ctrl+5)", "pad.toolbar.strikethrough.title": "Taie (Ctrl+5)",
"pad.toolbar.ol.title": "Listă ordonată (Ctrl+Shift+N)", "pad.toolbar.ol.title": "Listă ordonată (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Listă neordonată (Ctrl+Shift+L)", "pad.toolbar.ul.title": "Listă neordonată (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Cursiv (TAB)",
"pad.toolbar.unindent.title": "Fără cursiv (Shift+TAB)",
"pad.toolbar.undo.title": "Anulează (Ctrl+Z)", "pad.toolbar.undo.title": "Anulează (Ctrl+Z)",
"pad.toolbar.redo.title": "Refă (Ctrl+Y)", "pad.toolbar.redo.title": "Refă (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Curăță culorile autorilor (Ctrl+Shift+C)", "pad.toolbar.clearAuthorship.title": "Curăță culorile autorilor (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Importă/Exportă din/în diferite formate", "pad.toolbar.import_export.title": "Importă/Exportă din/în diferite formate",
"pad.toolbar.timeslider.title": "Glisor de timp",
"pad.toolbar.savedRevision.title": "Salvează revizia", "pad.toolbar.savedRevision.title": "Salvează revizia",
"pad.toolbar.settings.title": "Setări", "pad.toolbar.settings.title": "Setări",
"pad.toolbar.embed.title": "Partajați și încorporați acest pad",
"pad.toolbar.showusers.title": "Arată utilizatorii de pe acest pad", "pad.toolbar.showusers.title": "Arată utilizatorii de pe acest pad",
"pad.colorpicker.save": "Salvează", "pad.colorpicker.save": "Salvează",
"pad.colorpicker.cancel": "Anulează", "pad.colorpicker.cancel": "Anulează",
"pad.loading": "Se încarcă...", "pad.loading": "Se încarcă...",
"pad.noCookie": "Cookie-ul nu a putut fi găsit. Vă rugăm să permiteți cookie-urile în browser! Sesiunea și setările nu vor fi salvate între vizite. Aceasta se poate datora faptului că Etherpad este inclus într-un iFrame în unele browsere. Vă rugăm să vă asigurați că Etherpad este pe același subdomeniu/domeniu ca iFrame părinte",
"pad.passwordRequired": "Ai nevoie de o parolă pentru a accesa acest pad", "pad.passwordRequired": "Ai nevoie de o parolă pentru a accesa acest pad",
"pad.permissionDenied": "Nu ai permisiunea să accesezi acest pad", "pad.permissionDenied": "Nu ai permisiunea să accesezi acest pad",
"pad.wrongPassword": "Parola ta este greșită", "pad.wrongPassword": "Parola ta este greșită",
"pad.settings.padSettings": "Setări pentru Pad", "pad.settings.padSettings": "Setări pentru Pad",
"pad.settings.myView": "Perspectiva mea",
"pad.settings.stickychat": "Chat-ul întotdeauna pe ecran", "pad.settings.stickychat": "Chat-ul întotdeauna pe ecran",
"pad.settings.chatandusers": "Afișează Chat-ul și Utilizatorii", "pad.settings.chatandusers": "Afișează Chat-ul și Utilizatorii",
"pad.settings.colorcheck": "Culorile autorilor", "pad.settings.colorcheck": "Culorile autorilor",
"pad.settings.linenocheck": "Numere de linie", "pad.settings.linenocheck": "Numere de linie",
"pad.settings.rtlcheck": "Citiți conținut de la dreapta la stânga?",
"pad.settings.fontType": "Tipul fontului:", "pad.settings.fontType": "Tipul fontului:",
"pad.settings.language": "Limbă:", "pad.settings.language": "Limbă:",
"pad.settings.about": "Despre",
"pad.importExport.import_export": "Import/Export", "pad.importExport.import_export": "Import/Export",
"pad.importExport.import": "Încarcă orice fișier text sau document", "pad.importExport.import": "Încarcă orice fișier text sau document",
"pad.importExport.importSuccessful": "Succes!", "pad.importExport.importSuccessful": "Succes!",
@ -46,19 +57,33 @@
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)", "pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Puteți importa doar din format simplu sau HTML. Pentru funcții de import mai avansate, vă rugăm <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instalați AbiWord sau LibreOffice</a>.",
"pad.modals.connected": "Conectat.", "pad.modals.connected": "Conectat.",
"pad.modals.reconnecting": "Se reconectează la pad-ul dumneavoastră..", "pad.modals.reconnecting": "Se reconectează la pad-ul dumneavoastră..",
"pad.modals.forcereconnect": "Forțează reconectarea", "pad.modals.forcereconnect": "Forțează reconectarea",
"pad.modals.reconnecttimer": "Încercați să vă reconectați în",
"pad.modals.cancel": "Anulează",
"pad.modals.userdup": "Deschis în altă fereastră", "pad.modals.userdup": "Deschis în altă fereastră",
"pad.modals.userdup.explanation": "Acest pad pare a fi deschis în mai multe ferestre de browser de pe acest computer.",
"pad.modals.userdup.advice": "Reconectați-vă dacă doriți să utilizați această fereastră.", "pad.modals.userdup.advice": "Reconectați-vă dacă doriți să utilizați această fereastră.",
"pad.modals.unauth": "Nu ești autorizat", "pad.modals.unauth": "Nu ești autorizat",
"pad.modals.unauth.explanation": "Permisiunile dvs. s-au schimbat în timpul vizualizării acestei pagini. Încercați să vă reconectați.",
"pad.modals.looping.explanation": "Există probleme de comunicare cu serverul de sincronizare.",
"pad.modals.looping.cause": "Poate că v-ați conectat printr-un firewall sau proxy incompatibil.",
"pad.modals.initsocketfail": "Serverul nu este disponibil.", "pad.modals.initsocketfail": "Serverul nu este disponibil.",
"pad.modals.initsocketfail.explanation": "Nu s-a putut conecta la serverul de sincronizare.", "pad.modals.initsocketfail.explanation": "Nu s-a putut conecta la serverul de sincronizare.",
"pad.modals.initsocketfail.cause": "Acest lucru se datorează probabil unei probleme cu browserul sau conexiunea la internet.",
"pad.modals.slowcommit.explanation": "Serverul nu răspunde.", "pad.modals.slowcommit.explanation": "Serverul nu răspunde.",
"pad.modals.slowcommit.cause": "Aceasta poate fi cauzată de probleme cu conexiunea la rețea.", "pad.modals.slowcommit.cause": "Aceasta poate fi cauzată de probleme cu conexiunea la rețea.",
"pad.modals.badChangeset.explanation": "O editare pe care ai făcut-o a fost clasificată ilegal de serverul de sincronizare.",
"pad.modals.badChangeset.cause": "Aceasta s-ar putea datora unei configurații greșite a serverului sau a unui alt comportament neașteptat. Vă rugăm să contactați administratorul de serviciu, dacă considerați că aceasta este o eroare. Încercați să vă reconectați pentru a continua editarea.",
"pad.modals.corruptPad.explanation": "Pad-ul pe care încercați să îl accesați este corupt.",
"pad.modals.corruptPad.cause": "Aceasta se poate datora unei configurații greșite a serverului sau a unui alt comportament neașteptat. Vă rugăm să contactați administratorul de servicii.",
"pad.modals.deleted": "Șters.", "pad.modals.deleted": "Șters.",
"pad.modals.deleted.explanation": "Acest pad a fost șters.", "pad.modals.deleted.explanation": "Acest pad a fost șters.",
"pad.modals.disconnected": "Ai fost deconectat.", "pad.modals.disconnected": "Ai fost deconectat.",
"pad.modals.disconnected.explanation": "S-a pierdut conexiunea la server",
"pad.modals.disconnected.cause": "Este posibil ca serverul să nu fie disponibil. Vă rugăm să anunțați administratorul de servicii dacă acest lucru se întâmplă în continuare.",
"pad.share": "Distribuie acest pad", "pad.share": "Distribuie acest pad",
"pad.share.readonly": "Doar în citire", "pad.share.readonly": "Doar în citire",
"pad.share.link": "Legătură", "pad.share.link": "Legătură",
@ -66,6 +91,9 @@
"pad.chat": "Chat", "pad.chat": "Chat",
"pad.chat.title": "Deschide chat-ul pentru acest pad.", "pad.chat.title": "Deschide chat-ul pentru acest pad.",
"pad.chat.loadmessages": "Încarcă mai multe mesaje", "pad.chat.loadmessages": "Încarcă mai multe mesaje",
"pad.chat.stick.title": "Lipiți chatul pe ecran",
"pad.chat.writeMessage.placeholder": "Scrie-ți mesajul aici",
"timeslider.pageTitle": "{{appTitle}} Glisor de timp",
"timeslider.toolbar.returnbutton": "Înapoi la pad", "timeslider.toolbar.returnbutton": "Înapoi la pad",
"timeslider.toolbar.authors": "Autori:", "timeslider.toolbar.authors": "Autori:",
"timeslider.toolbar.authorsList": "Niciun autor", "timeslider.toolbar.authorsList": "Niciun autor",
@ -73,6 +101,9 @@
"timeslider.exportCurrent": "Exportă versiunea curentă ca:", "timeslider.exportCurrent": "Exportă versiunea curentă ca:",
"timeslider.version": "Versiunea {{version}}", "timeslider.version": "Versiunea {{version}}",
"timeslider.saved": "Salvat pe {{day}} {{month}} {{year}}", "timeslider.saved": "Salvat pe {{day}} {{month}} {{year}}",
"timeslider.playPause": "Redare / Pauză conținut Pad",
"timeslider.backRevision": "Reveniți la o revizuire în acest Pad",
"timeslider.forwardRevision": "Continuați o revizuire în acest Pad",
"timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}", "timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "ianuarie", "timeslider.month.january": "ianuarie",
"timeslider.month.february": "februarie", "timeslider.month.february": "februarie",
@ -86,12 +117,24 @@
"timeslider.month.october": "octombrie", "timeslider.month.october": "octombrie",
"timeslider.month.november": "noiembrie", "timeslider.month.november": "noiembrie",
"timeslider.month.december": "decembrie", "timeslider.month.december": "decembrie",
"timeslider.unnamedauthors": "{{num}} anonim {[plural (num) unul: autor, altul: autori ]}",
"pad.savedrevs.marked": "Această revizie este marcată acum ca o revizuire salvată",
"pad.savedrevs.timeslider": "Puteți vedea reviziile salvate accesând cursorul de timp",
"pad.userlist.entername": "Introduceți numele dumneavoastră", "pad.userlist.entername": "Introduceți numele dumneavoastră",
"pad.userlist.unnamed": "fără nume", "pad.userlist.unnamed": "fără nume",
"pad.userlist.guest": "Oaspete", "pad.userlist.guest": "Oaspete",
"pad.userlist.deny": "Respinge", "pad.userlist.deny": "Respinge",
"pad.userlist.approve": "Aprobă", "pad.userlist.approve": "Aprobă",
"pad.editbar.clearcolors": "Ștergeți culorile de autor pe întreg documentul? Acest lucru nu poate fi anulat",
"pad.impexp.importbutton": "Importă acum", "pad.impexp.importbutton": "Importă acum",
"pad.impexp.importing": "Importare...", "pad.impexp.importing": "Importare...",
"pad.impexp.importfailed": "Import eșuat" "pad.impexp.confirmimport": "Importarea unui fișier va suprascrie textul curent al padului. Ești sigur că vrei să continui?",
"pad.impexp.convertFailed": "Nu am putut importa acest fișier. Vă rugăm să utilizați un alt format de document sau să copiați pasta manual",
"pad.impexp.padHasData": "Nu am putut importa acest fișier, deoarece acest Pad a avut deja modificări, vă rugăm să importați pe un nou pad",
"pad.impexp.uploadFailed": "Încărcarea a eșuat. Încercați din nou",
"pad.impexp.importfailed": "Import eșuat",
"pad.impexp.copypaste": "Vă rugăm să copiați și să lipiți",
"pad.impexp.exportdisabled": "Exportul ca format {{type}} este dezactivat. Vă rugăm să contactați administratorul de sistem pentru detalii.",
"pad.impexp.maxFileSize": "Fișier prea mare. Contactați administratorul site-ului pentru a crește dimensiunea permisă a fișierului pentru import",
"pad.impexp.permission": "Importul este dezactivat deoarece nu ați contribuit niciodată la această placă. Vă rugăm să contribuiți cel puțin o dată înainte de import"
} }

View file

@ -6,17 +6,20 @@
"Diralik", "Diralik",
"Eleferen", "Eleferen",
"Facenapalm", "Facenapalm",
"MSClaudiu",
"Movses", "Movses",
"Nzeemin", "Nzeemin",
"Okras", "Okras",
"Patrick Star", "Patrick Star",
"Teretalexev",
"Volkov" "Volkov"
] ]
}, },
"index.newPad": "Создать", "index.newPad": "Создать",
"index.createOpenPad": "или создать/открыть документ с именем:", "index.createOpenPad": "или создать/открыть документ с именем:",
"pad.toolbar.bold.title": "полужирный (Ctrl-B)", "index.openPad": "откройте существующий документ с именем:",
"pad.toolbar.italic.title": "курсив (Ctrl-I)", "pad.toolbar.bold.title": "Полужирный (Ctrl-B)",
"pad.toolbar.italic.title": "Курсив (Ctrl-I)",
"pad.toolbar.underline.title": "подчёркивание (Ctrl-U)", "pad.toolbar.underline.title": "подчёркивание (Ctrl-U)",
"pad.toolbar.strikethrough.title": "Зачёркивание (Ctrl+5)", "pad.toolbar.strikethrough.title": "Зачёркивание (Ctrl+5)",
"pad.toolbar.ol.title": "Упорядоченный список (Ctrl+Shift+N)", "pad.toolbar.ol.title": "Упорядоченный список (Ctrl+Shift+N)",
@ -26,7 +29,7 @@
"pad.toolbar.undo.title": "Отменить (Ctrl-Z)", "pad.toolbar.undo.title": "Отменить (Ctrl-Z)",
"pad.toolbar.redo.title": "Вернуть (Ctrl-Y)", "pad.toolbar.redo.title": "Вернуть (Ctrl-Y)",
"pad.toolbar.clearAuthorship.title": "Очистить цвета документа (Ctrl+Shift+C)", "pad.toolbar.clearAuthorship.title": "Очистить цвета документа (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Импорт/экспорт с использованием различных форматов файлов", "pad.toolbar.import_export.title": "Импорт/экспорт из/в другие форматы файлов",
"pad.toolbar.timeslider.title": "Шкала времени", "pad.toolbar.timeslider.title": "Шкала времени",
"pad.toolbar.savedRevision.title": "Сохранить версию", "pad.toolbar.savedRevision.title": "Сохранить версию",
"pad.toolbar.settings.title": "Настройки", "pad.toolbar.settings.title": "Настройки",
@ -35,7 +38,7 @@
"pad.colorpicker.save": "Сохранить", "pad.colorpicker.save": "Сохранить",
"pad.colorpicker.cancel": "Отмена", "pad.colorpicker.cancel": "Отмена",
"pad.loading": "Загрузка...", "pad.loading": "Загрузка...",
"pad.noCookie": "Куки не найдены. Пожалуйста, включите куки в вашем браузере!", "pad.noCookie": "Куки не найдены. Пожалуйста, включите куки в вашем браузере! Ваш сеанс и настройки не будут сохранены между посещениями. Это может быть связано с тем, что Etherpad включен в iFrame в некоторых браузерах. Убедитесь, что Etherpad находится в том же поддомене/домене, что и родительский iFrame.",
"pad.passwordRequired": "Вам нужен пароль для доступа", "pad.passwordRequired": "Вам нужен пароль для доступа",
"pad.permissionDenied": "У вас нет разрешения на доступ", "pad.permissionDenied": "У вас нет разрешения на доступ",
"pad.wrongPassword": "Неправильный пароль", "pad.wrongPassword": "Неправильный пароль",
@ -49,6 +52,8 @@
"pad.settings.fontType": "Тип шрифта:", "pad.settings.fontType": "Тип шрифта:",
"pad.settings.fontType.normal": "Обычный", "pad.settings.fontType.normal": "Обычный",
"pad.settings.language": "Язык:", "pad.settings.language": "Язык:",
"pad.settings.about": "О проекте",
"pad.settings.poweredBy": "Проект основан на",
"pad.importExport.import_export": "Импорт/экспорт", "pad.importExport.import_export": "Импорт/экспорт",
"pad.importExport.import": "Загрузить любой текстовый файл или документ", "pad.importExport.import": "Загрузить любой текстовый файл или документ",
"pad.importExport.importSuccessful": "Успешно!", "pad.importExport.importSuccessful": "Успешно!",
@ -83,6 +88,8 @@
"pad.modals.corruptPad.cause": "Это может быть из-за неправильной конфигурации сервера или некоторых других неожиданных действий. Пожалуйста, свяжитесь с администратором службы.", "pad.modals.corruptPad.cause": "Это может быть из-за неправильной конфигурации сервера или некоторых других неожиданных действий. Пожалуйста, свяжитесь с администратором службы.",
"pad.modals.deleted": "Удалён.", "pad.modals.deleted": "Удалён.",
"pad.modals.deleted.explanation": "Этот документ был удалён.", "pad.modals.deleted.explanation": "Этот документ был удалён.",
"pad.modals.rateLimited": "Скорость ограничена.",
"pad.modals.rateLimited.explanation": "Вы отправили слишком много сообщений в этот документ, поэтому вы были отключены.",
"pad.modals.disconnected": "Соединение разорвано.", "pad.modals.disconnected": "Соединение разорвано.",
"pad.modals.disconnected.explanation": "Подключение к серверу потеряно", "pad.modals.disconnected.explanation": "Подключение к серверу потеряно",
"pad.modals.disconnected.cause": "Сервер, возможно, недоступен. Пожалуйста, сообщите администратору службы, если проблема будет повторятся.", "pad.modals.disconnected.cause": "Сервер, возможно, недоступен. Пожалуйста, сообщите администратору службы, если проблема будет повторятся.",
@ -95,8 +102,9 @@
"pad.chat.loadmessages": "Ещё сообщения", "pad.chat.loadmessages": "Ещё сообщения",
"pad.chat.stick.title": "Закрепить чат на экране", "pad.chat.stick.title": "Закрепить чат на экране",
"pad.chat.writeMessage.placeholder": "Напишите своё сообщение сюда", "pad.chat.writeMessage.placeholder": "Напишите своё сообщение сюда",
"timeslider.followContents": "Следить за обновлениями содержимого документа",
"timeslider.pageTitle": "Временная шкала {{appTitle}}", "timeslider.pageTitle": "Временная шкала {{appTitle}}",
"timeslider.toolbar.returnbutton": "К документу", "timeslider.toolbar.returnbutton": "Вернуться к документу",
"timeslider.toolbar.authors": "Авторы:", "timeslider.toolbar.authors": "Авторы:",
"timeslider.toolbar.authorsList": "Нет авторов", "timeslider.toolbar.authorsList": "Нет авторов",
"timeslider.toolbar.exportlink.title": "Экспорт", "timeslider.toolbar.exportlink.title": "Экспорт",

View file

@ -1,6 +1,7 @@
{ {
"@metadata": { "@metadata": {
"authors": [ "authors": [
"BaRaN6161 TURK",
"Mehtab ahmed", "Mehtab ahmed",
"Tweety" "Tweety"
] ]
@ -66,7 +67,7 @@
"timeslider.toolbar.exportlink.title": "برآمد ڪريو", "timeslider.toolbar.exportlink.title": "برآمد ڪريو",
"timeslider.version": "ورزن {{version}}", "timeslider.version": "ورزن {{version}}",
"timeslider.saved": "سانڍيل {{month}} {{day}}، {{year}}", "timeslider.saved": "سانڍيل {{month}} {{day}}، {{year}}",
"timeslider.dateformat": "{{مهينو}}/{{ڏينهن}}/{{سال}} {{ڪلاڪ}}:{{منٽ}}:{{سيڪنڊ}}", "timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "جنوري", "timeslider.month.january": "جنوري",
"timeslider.month.february": "فيبروري", "timeslider.month.february": "فيبروري",
"timeslider.month.march": "مارچ", "timeslider.month.march": "مارچ",

View file

@ -7,6 +7,7 @@
"Milicevic01", "Milicevic01",
"Obsuser", "Obsuser",
"Srdjan m", "Srdjan m",
"Srđan",
"Милан Јелисавчић" "Милан Јелисавчић"
] ]
}, },
@ -46,6 +47,8 @@
"pad.settings.fontType": "Врста фонта:", "pad.settings.fontType": "Врста фонта:",
"pad.settings.fontType.normal": "Нормално", "pad.settings.fontType.normal": "Нормално",
"pad.settings.language": "Језик:", "pad.settings.language": "Језик:",
"pad.settings.about": "О пројекту",
"pad.settings.poweredBy": "Покреће",
"pad.importExport.import_export": "Увоз/извоз", "pad.importExport.import_export": "Увоз/извоз",
"pad.importExport.import": "Отпремите било коју текстуалну датотеку или документ", "pad.importExport.import": "Отпремите било коју текстуалну датотеку или документ",
"pad.importExport.importSuccessful": "Успешно!", "pad.importExport.importSuccessful": "Успешно!",

View file

@ -3,21 +3,23 @@
"authors": [ "authors": [
"Jopparn", "Jopparn",
"Lokal Profil", "Lokal Profil",
"Sabelöga",
"WikiPhoenix" "WikiPhoenix"
] ]
}, },
"index.newPad": "Nytt block", "index.newPad": "Nytt block",
"index.createOpenPad": "eller skapa/öppna ett block med namnet:", "index.createOpenPad": "eller skapa/öppna ett block med namnet:",
"pad.toolbar.bold.title": "Fet (Ctrl-B)", "index.openPad": "öppna ett befintligt block med namnet:",
"pad.toolbar.italic.title": "Kursiv (Ctrl-I)", "pad.toolbar.bold.title": "Fet (Ctrl+B)",
"pad.toolbar.underline.title": "Understruken (Ctrl-U)", "pad.toolbar.italic.title": "Kursiv (Ctrl+I)",
"pad.toolbar.underline.title": "Understruken (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Genomstruken (Ctrl+5)", "pad.toolbar.strikethrough.title": "Genomstruken (Ctrl+5)",
"pad.toolbar.ol.title": "Numrerad lista (Ctrl+Shift+N)", "pad.toolbar.ol.title": "Numrerad lista (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Onumrerad lista (Ctrl+Shift+L)", "pad.toolbar.ul.title": "Onumrerad lista (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Öka indrag (TABB)", "pad.toolbar.indent.title": "Öka indrag (TABB)",
"pad.toolbar.unindent.title": "Minska indrag (Shift+TABB)", "pad.toolbar.unindent.title": "Minska indrag (Shift+TABB)",
"pad.toolbar.undo.title": "Ångra (Ctrl-Z)", "pad.toolbar.undo.title": "Ångra (Ctrl+Z)",
"pad.toolbar.redo.title": "Gör om (Ctrl-Y)", "pad.toolbar.redo.title": "Gör om (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Rensa författarfärger (Ctrl+Shift+C)", "pad.toolbar.clearAuthorship.title": "Rensa författarfärger (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Importera/exportera från/till olika filformat", "pad.toolbar.import_export.title": "Importera/exportera från/till olika filformat",
"pad.toolbar.timeslider.title": "Tidsreglage", "pad.toolbar.timeslider.title": "Tidsreglage",
@ -28,7 +30,7 @@
"pad.colorpicker.save": "Spara", "pad.colorpicker.save": "Spara",
"pad.colorpicker.cancel": "Avbryt", "pad.colorpicker.cancel": "Avbryt",
"pad.loading": "Läser in...", "pad.loading": "Läser in...",
"pad.noCookie": "Kunde inte hitta några kakor. Var god tillåt kakor i din webbläsare!", "pad.noCookie": "Kunde inte hitta några kakor. Var god tillåt kakor i din webbläsare! Din session och inställningar kommer inte sparas mellan dina besök. Detta kan bero på att Etherpad inte ligger inuti en iFrame i vissa webbläsare. Se till att Etherpad är i samma underdomän/domän som det överordnade iFrame-elementet.",
"pad.passwordRequired": "Du behöver ett lösenord för att få tillgång till detta block", "pad.passwordRequired": "Du behöver ett lösenord för att få tillgång till detta block",
"pad.permissionDenied": "Du har inte åtkomstbehörighet för detta block", "pad.permissionDenied": "Du har inte åtkomstbehörighet för detta block",
"pad.wrongPassword": "Ditt lösenord var fel", "pad.wrongPassword": "Ditt lösenord var fel",
@ -42,10 +44,12 @@
"pad.settings.fontType": "Typsnitt:", "pad.settings.fontType": "Typsnitt:",
"pad.settings.fontType.normal": "Normal", "pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Språk:", "pad.settings.language": "Språk:",
"pad.settings.about": "Om",
"pad.settings.poweredBy": "Drivs av",
"pad.importExport.import_export": "Importera/Exportera", "pad.importExport.import_export": "Importera/Exportera",
"pad.importExport.import": "Ladda upp textfiler eller dokument", "pad.importExport.import": "Ladda upp textfiler eller dokument",
"pad.importExport.importSuccessful": "Åtgärden slutfördes!", "pad.importExport.importSuccessful": "Åtgärden slutfördes!",
"pad.importExport.export": "Export aktuellt block som:", "pad.importExport.export": "Exportera aktuellt block som:",
"pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML", "pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Oformaterad text", "pad.importExport.exportplain": "Oformaterad text",
@ -76,6 +80,8 @@
"pad.modals.corruptPad.cause": "Detta kan bero på en felaktig konfiguration av servern eller något annat oväntad beteende. Var god kontakta tjänstadministratören.", "pad.modals.corruptPad.cause": "Detta kan bero på en felaktig konfiguration av servern eller något annat oväntad beteende. Var god kontakta tjänstadministratören.",
"pad.modals.deleted": "Raderad.", "pad.modals.deleted": "Raderad.",
"pad.modals.deleted.explanation": "Detta block har tagits bort.", "pad.modals.deleted.explanation": "Detta block har tagits bort.",
"pad.modals.rateLimited": "Begränsad frekvens.",
"pad.modals.rateLimited.explanation": "Du skickade för många meddelanden till detta block så du blev frånkopplad.",
"pad.modals.disconnected": "Du har blivit frånkopplad.", "pad.modals.disconnected": "Du har blivit frånkopplad.",
"pad.modals.disconnected.explanation": "Anslutningen till servern avbröts", "pad.modals.disconnected.explanation": "Anslutningen till servern avbröts",
"pad.modals.disconnected.cause": "Servern kanske är otillgänglig. Var god meddela tjänstadministratören om detta fortsätter att hända.", "pad.modals.disconnected.cause": "Servern kanske är otillgänglig. Var god meddela tjänstadministratören om detta fortsätter att hända.",
@ -88,6 +94,7 @@
"pad.chat.loadmessages": "Läs in fler meddelanden", "pad.chat.loadmessages": "Läs in fler meddelanden",
"pad.chat.stick.title": "Fäst chatten på skärmen", "pad.chat.stick.title": "Fäst chatten på skärmen",
"pad.chat.writeMessage.placeholder": "Skriv ditt meddelande här", "pad.chat.writeMessage.placeholder": "Skriv ditt meddelande här",
"timeslider.followContents": "Följ uppdateringar om blockets innehåll",
"timeslider.pageTitle": "{{appTitle}} tidsreglage", "timeslider.pageTitle": "{{appTitle}} tidsreglage",
"timeslider.toolbar.returnbutton": "Återvänd till blocket", "timeslider.toolbar.returnbutton": "Återvänd till blocket",
"timeslider.toolbar.authors": "Författare:", "timeslider.toolbar.authors": "Författare:",
@ -131,5 +138,5 @@
"pad.impexp.copypaste": "Var god kopiera och klistra in", "pad.impexp.copypaste": "Var god kopiera och klistra in",
"pad.impexp.exportdisabled": "Exportering av formatet {{type}} är inaktiverad. Var god kontakta din systemadministratör för mer information.", "pad.impexp.exportdisabled": "Exportering av formatet {{type}} är inaktiverad. Var god kontakta din systemadministratör för mer information.",
"pad.impexp.maxFileSize": "Filen är för stor. Kontakta din systemadministratör för att öka den tillåtna filstorleken för importering", "pad.impexp.maxFileSize": "Filen är för stor. Kontakta din systemadministratör för att öka den tillåtna filstorleken för importering",
"pad.impexp.permission": "Import är inaktiverat eftersom du aldrig har bidragit detta block. var god bidra minst en gång innan du importerar" "pad.impexp.permission": "Importering är inaktiverat eftersom du aldrig har bidragit till detta block. Var god bidra minst en gång innan du importerar"
} }

View file

@ -39,6 +39,7 @@
"pad.settings.fontType": "అక్షరశైలి రకం:", "pad.settings.fontType": "అక్షరశైలి రకం:",
"pad.settings.fontType.normal": "సాధారణ", "pad.settings.fontType.normal": "సాధారణ",
"pad.settings.language": "భాష", "pad.settings.language": "భాష",
"pad.settings.about": "గురించి",
"pad.importExport.import_export": "దిగుమతి/ఎగుమతి", "pad.importExport.import_export": "దిగుమతి/ఎగుమతి",
"pad.importExport.import": "పాఠము దస్త్రము లేదా పత్రమును దిగుమతి చేయుము", "pad.importExport.import": "పాఠము దస్త్రము లేదా పత్రమును దిగుమతి చేయుము",
"pad.importExport.importSuccessful": "విజయవంతం!", "pad.importExport.importSuccessful": "విజయవంతం!",

View file

@ -1,11 +1,13 @@
{ {
"@metadata": { "@metadata": {
"authors": [ "authors": [
"Aefgh39622" "Aefgh39622",
"Patsagorn Y."
] ]
}, },
"index.newPad": "สร้างแผ่นจดบันทึกใหม่", "index.newPad": "สร้างแผ่นจดบันทึกใหม่",
"index.createOpenPad": "หรือสร้าง/เปิดแผ่นจดบันทึกที่มีชื่อ:", "index.createOpenPad": "หรือสร้าง/เปิดแผ่นจดบันทึกที่มีชื่อ:",
"index.openPad": "เปิดแพดที่มีอยู่แล้วด้วยชื่อ:",
"pad.toolbar.bold.title": "ตัวหนา (Ctrl+B)", "pad.toolbar.bold.title": "ตัวหนา (Ctrl+B)",
"pad.toolbar.italic.title": "ตัวเอียง (Ctrl+I)", "pad.toolbar.italic.title": "ตัวเอียง (Ctrl+I)",
"pad.toolbar.underline.title": "ขีดเส้นใต้ (Ctrl+U)", "pad.toolbar.underline.title": "ขีดเส้นใต้ (Ctrl+U)",
@ -26,10 +28,10 @@
"pad.colorpicker.save": "บันทึก", "pad.colorpicker.save": "บันทึก",
"pad.colorpicker.cancel": "ยกเลิก", "pad.colorpicker.cancel": "ยกเลิก",
"pad.loading": "กำลังโหลด...", "pad.loading": "กำลังโหลด...",
"pad.noCookie": "ไม่พบคุกกี้ โปรดเปิดใช้งานคุกกี้ในเบราว์เซอร์ของคุณ!", "pad.noCookie": "ไม่พบคุกกี้ กรุณาอนุญาติคุกกี้บนเบราว์เซอร์ของคุณ การเข้าสู่ระบบและการตั้งค่าจะไม่ถูกบันทึกขณะเยี่ยมชม อาจเกิดปัญหาจากอีเทอร์แพดถูกฝังไว้ในหน้าผ่าน iFrame ในบางเบราว์เซอร์ กรุณาตรวจสอบว่าอีเทอร์แพดอยู่ในโดเมนหรือโดเมนรองเดียวกันกับหน้าที่ฝัง iFrame",
"pad.passwordRequired": "คุณต้องใช้รหัสผ่านเพื่อเข้าถึงแผ่นจดบันทึกนี้", "pad.passwordRequired": "คุณต้องใช้รหัสผ่านเพื่อเข้าถึงแผ่นจดบันทึกนี้",
"pad.permissionDenied": "คุณไม่มีสิทธิ์เข้าถึงแผ่นจดบันทึกนี้", "pad.permissionDenied": "คุณไม่มีสิทธิ์เข้าถึงแผ่นจดบันทึกนี้",
"pad.wrongPassword": "รหัสผ่านของคุณผิด", "pad.wrongPassword": "รหัสผ่านไม่ถูกต้อง",
"pad.settings.padSettings": "การตั้งค่าแผ่นจดบันทึก", "pad.settings.padSettings": "การตั้งค่าแผ่นจดบันทึก",
"pad.settings.myView": "มุมมองของฉัน", "pad.settings.myView": "มุมมองของฉัน",
"pad.settings.stickychat": "แสดงการแชทบนหน้าจอเสมอ", "pad.settings.stickychat": "แสดงการแชทบนหน้าจอเสมอ",
@ -39,6 +41,8 @@
"pad.settings.rtlcheck": "อ่านเนื้อหาจากขวาไปซ้ายหรือไม่?", "pad.settings.rtlcheck": "อ่านเนื้อหาจากขวาไปซ้ายหรือไม่?",
"pad.settings.fontType": "ชนิดแบบอักษร:", "pad.settings.fontType": "ชนิดแบบอักษร:",
"pad.settings.language": "ภาษา:", "pad.settings.language": "ภาษา:",
"pad.settings.about": "เกี่ยวกับ",
"pad.settings.poweredBy": "ขับเคลื่อนโดย $1",
"pad.importExport.import_export": "นำเข้า/ส่งออก", "pad.importExport.import_export": "นำเข้า/ส่งออก",
"pad.importExport.import": "อัปโหลดไฟล์ข้อความหรือเอกสารใดๆ", "pad.importExport.import": "อัปโหลดไฟล์ข้อความหรือเอกสารใดๆ",
"pad.importExport.importSuccessful": "สำเร็จ!", "pad.importExport.importSuccessful": "สำเร็จ!",
@ -49,7 +53,7 @@
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)", "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.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 หรือ LibraOffice</a>",
"pad.modals.connected": "เชื่อมต่อแล้ว", "pad.modals.connected": "เชื่อมต่อแล้ว",
"pad.modals.reconnecting": "กำลังเชื่อมต่อกับแผ่นจดบันทึกของคุณใหม่..", "pad.modals.reconnecting": "กำลังเชื่อมต่อกับแผ่นจดบันทึกของคุณใหม่..",
"pad.modals.forcereconnect": "บังคับเชื่อมต่อใหม่", "pad.modals.forcereconnect": "บังคับเชื่อมต่อใหม่",
@ -73,6 +77,8 @@
"pad.modals.corruptPad.cause": "อาจเป็นเนื่องจากการกำหนดค่าเซิร์ฟเวอร์ไม่ถูกต้องหรือมีลักษณะการทำงานอื่นๆ บางอย่างที่ไม่คาดคิด โปรดติดต่อผู้ดูแลการให้บริการ", "pad.modals.corruptPad.cause": "อาจเป็นเนื่องจากการกำหนดค่าเซิร์ฟเวอร์ไม่ถูกต้องหรือมีลักษณะการทำงานอื่นๆ บางอย่างที่ไม่คาดคิด โปรดติดต่อผู้ดูแลการให้บริการ",
"pad.modals.deleted": "ลบแล้ว", "pad.modals.deleted": "ลบแล้ว",
"pad.modals.deleted.explanation": "แผ่นจดบันทึกนี้ได้ถูกลบออกแล้ว", "pad.modals.deleted.explanation": "แผ่นจดบันทึกนี้ได้ถูกลบออกแล้ว",
"pad.modals.rateLimited": "ถึงขีดจำกัด",
"pad.modals.rateLimited.explanation": "คณส่งข้อความถึงแพดนี้มากเกินไปจึงถูกตัดการเชื่อมโดยโปรแกรมอัตโนมัติ",
"pad.modals.disconnected": "คุณได้ตัดการเชื่อมต่อแล้ว", "pad.modals.disconnected": "คุณได้ตัดการเชื่อมต่อแล้ว",
"pad.modals.disconnected.explanation": "การเชื่อมต่อกับเซิร์ฟเวอร์ถูกตัด", "pad.modals.disconnected.explanation": "การเชื่อมต่อกับเซิร์ฟเวอร์ถูกตัด",
"pad.modals.disconnected.cause": "เซิร์ฟเวอร์อาจใช้ไม่ได้ชั่วคราว โปรดแจ้งให้ผู้ดูแลการให้บริการทราบถ้าปัญหานี้ยังคงเกิดขึ้น", "pad.modals.disconnected.cause": "เซิร์ฟเวอร์อาจใช้ไม่ได้ชั่วคราว โปรดแจ้งให้ผู้ดูแลการให้บริการทราบถ้าปัญหานี้ยังคงเกิดขึ้น",
@ -83,6 +89,9 @@
"pad.chat": "แชท", "pad.chat": "แชท",
"pad.chat.title": "เปิดการแชทสำหรับแผ่นจดบันทึกนี้", "pad.chat.title": "เปิดการแชทสำหรับแผ่นจดบันทึกนี้",
"pad.chat.loadmessages": "โหลดข้อความเพิ่มเติม", "pad.chat.loadmessages": "โหลดข้อความเพิ่มเติม",
"pad.chat.stick.title": "ปักการสนทนาไว้บนหน้าจอ",
"pad.chat.writeMessage.placeholder": "เขียนข้อความ...",
"timeslider.followContents": "ติดตามการอัพเดตเนื้อหาแพด",
"timeslider.pageTitle": "ตัวเลื่อนเวลา {{appTitle}}", "timeslider.pageTitle": "ตัวเลื่อนเวลา {{appTitle}}",
"timeslider.toolbar.returnbutton": "กลับไปแผ่นจดบันทึก", "timeslider.toolbar.returnbutton": "กลับไปแผ่นจดบันทึก",
"timeslider.toolbar.authors": "ผู้เขียน:", "timeslider.toolbar.authors": "ผู้เขียน:",
@ -112,11 +121,11 @@
"pad.savedrevs.timeslider": "คุณสามารถดูรุ่นแก้ไขที่บันทึกแล้วโดยเยี่ยมชมตัวเลื่อนเวลา", "pad.savedrevs.timeslider": "คุณสามารถดูรุ่นแก้ไขที่บันทึกแล้วโดยเยี่ยมชมตัวเลื่อนเวลา",
"pad.userlist.entername": "กรอกชื่อของคุณ", "pad.userlist.entername": "กรอกชื่อของคุณ",
"pad.userlist.unnamed": "ไม่มีชื่อ", "pad.userlist.unnamed": "ไม่มีชื่อ",
"pad.userlist.guest": "ผู้เยี่ยมชม", "pad.userlist.guest": "นิรนาม",
"pad.userlist.deny": "ปฏิเสธ", "pad.userlist.deny": "ปฏิเสธ",
"pad.userlist.approve": "อนุมัติ", "pad.userlist.approve": "อนุญาต",
"pad.editbar.clearcolors": "ล้างสีผู้เขียนบนทั้งเอกสารหรือไม่?", "pad.editbar.clearcolors": "ลบการเน้นความเป็นเจ้าของข้อความหรือไม่? การกระทำนี่ไม่สามารถย้อนได้",
"pad.impexp.importbutton": "นำเข้าเดี๋ยวนี้", "pad.impexp.importbutton": "นำเข้าตอนนี้",
"pad.impexp.importing": "กำลังนำเข้า...", "pad.impexp.importing": "กำลังนำเข้า...",
"pad.impexp.confirmimport": "การนำเข้าไฟล์จะเป็นการเขียนทับข้อความปัจจุบันบนแผ่นจดบันทึก คุณแน่ใจหรือว่าคุณต้องการดำเนินการต่อ?", "pad.impexp.confirmimport": "การนำเข้าไฟล์จะเป็นการเขียนทับข้อความปัจจุบันบนแผ่นจดบันทึก คุณแน่ใจหรือว่าคุณต้องการดำเนินการต่อ?",
"pad.impexp.convertFailed": "เราไม่สามารถนำเข้าไฟล์นี้ได้ โปรดใช้รูปแบบเอกสารอื่นหรือคัดลอกแล้ววางด้วยตนเอง", "pad.impexp.convertFailed": "เราไม่สามารถนำเข้าไฟล์นี้ได้ โปรดใช้รูปแบบเอกสารอื่นหรือคัดลอกแล้ววางด้วยตนเอง",
@ -124,5 +133,7 @@
"pad.impexp.uploadFailed": "การอัปโหลดล้มเหลว โปรดลองอีกครั้ง", "pad.impexp.uploadFailed": "การอัปโหลดล้มเหลว โปรดลองอีกครั้ง",
"pad.impexp.importfailed": "การนำเข้าล้มเหลว", "pad.impexp.importfailed": "การนำเข้าล้มเหลว",
"pad.impexp.copypaste": "โปรดคัดลอกแล้ววาง", "pad.impexp.copypaste": "โปรดคัดลอกแล้ววาง",
"pad.impexp.exportdisabled": "การส่งออกเป็นรูปแบบ {{type}} ถูกปิดใช้งาน โปรดติดต่อผู้ดูแลระบบของคุณสำหรับรายละเอียดเพิ่มเติม" "pad.impexp.exportdisabled": "การส่งออกเป็นรูปแบบ {{type}} ถูกปิดใช้งาน โปรดติดต่อผู้ดูแลระบบของคุณสำหรับรายละเอียดเพิ่มเติม",
"pad.impexp.maxFileSize": "ไฟล์ใหญ่เกินไป ติดต่อผู้ดูแลไซต์เพื่อให้ขยายขนาดไฟล์ที่นำเข้าได้",
"pad.impexp.permission": "การนำเข้าถูกปิดเนื่องจากคุณไม่เคยมีส่วนร่วมในแพดนี้ กรุณามีส่วนร่วมซักครั้งหนึ่งก่อนนำเข้า"
} }

View file

@ -15,6 +15,7 @@
}, },
"index.newPad": "Yeni Bloknot", "index.newPad": "Yeni Bloknot",
"index.createOpenPad": "veya şu adla bir Bloknot oluşturun/açın:", "index.createOpenPad": "veya şu adla bir Bloknot oluşturun/açın:",
"index.openPad": "şu adla varolan bir Pad'i açın:",
"pad.toolbar.bold.title": "Kalın (Ctrl+B)", "pad.toolbar.bold.title": "Kalın (Ctrl+B)",
"pad.toolbar.italic.title": "Eğik (Ctrl+I)", "pad.toolbar.italic.title": "Eğik (Ctrl+I)",
"pad.toolbar.underline.title": "Altı Çizili (Ctrl+U)", "pad.toolbar.underline.title": "Altı Çizili (Ctrl+U)",
@ -35,7 +36,7 @@
"pad.colorpicker.save": "Kaydet", "pad.colorpicker.save": "Kaydet",
"pad.colorpicker.cancel": "İptal", "pad.colorpicker.cancel": "İptal",
"pad.loading": "Yükleniyor...", "pad.loading": "Yükleniyor...",
"pad.noCookie": "Çerez bulunamadı. Lütfen tarayıcınızda çerezlere izin veriniz!", "pad.noCookie": "Çerez bulunamadı. Lütfen tarayıcınızda çerezlere izin veriniz! Lütfen tarayıcınızda çerezlere izin verin! Oturumunuz ve ayarlarınız ziyaretler arasında kaydedilmez. Bunun nedeni, Etherpad'in bazı Tarayıcılarda bir iFrame'e dahil edilmiş olması olabilir. Lütfen Etherpad'in üst iFrame ile aynı alt alanda/alanda olduğundan emin olun",
"pad.passwordRequired": "Bu bloknota erişebilmeniz için parolaya ihtiyacınız var", "pad.passwordRequired": "Bu bloknota erişebilmeniz için parolaya ihtiyacınız var",
"pad.permissionDenied": "Bu bloknota erişmeye izniniz yok", "pad.permissionDenied": "Bu bloknota erişmeye izniniz yok",
"pad.wrongPassword": "Parolanız yanlış", "pad.wrongPassword": "Parolanız yanlış",
@ -49,6 +50,8 @@
"pad.settings.fontType": "Yazı tipi:", "pad.settings.fontType": "Yazı tipi:",
"pad.settings.fontType.normal": "Olağan", "pad.settings.fontType.normal": "Olağan",
"pad.settings.language": "Dil:", "pad.settings.language": "Dil:",
"pad.settings.about": "Hakkında",
"pad.settings.poweredBy": "Destekleyen",
"pad.importExport.import_export": "İçe/Dışa aktar", "pad.importExport.import_export": "İçe/Dışa aktar",
"pad.importExport.import": "Herhangi bir metin dosyası ya da belgesi yükle", "pad.importExport.import": "Herhangi bir metin dosyası ya da belgesi yükle",
"pad.importExport.importSuccessful": "Başarılı!", "pad.importExport.importSuccessful": "Başarılı!",
@ -83,11 +86,13 @@
"pad.modals.corruptPad.cause": "Bunun nedeni yanlış bir sunucu yapılandırması veya beklenmeyen başka bir davranış olabilir. Lütfen servis yöneticisine başvurun.", "pad.modals.corruptPad.cause": "Bunun nedeni yanlış bir sunucu yapılandırması veya beklenmeyen başka bir davranış olabilir. Lütfen servis yöneticisine başvurun.",
"pad.modals.deleted": "Silindi.", "pad.modals.deleted": "Silindi.",
"pad.modals.deleted.explanation": "Bu bloknot kaldırılmış.", "pad.modals.deleted.explanation": "Bu bloknot kaldırılmış.",
"pad.modals.rateLimited": "Oran Sınırlı.",
"pad.modals.rateLimited.explanation": "Bu pad'e çok fazla mesaj gönderdiniz, böylece bağlantı kesildi.",
"pad.modals.disconnected": "Bağlantınız koptu.", "pad.modals.disconnected": "Bağlantınız koptu.",
"pad.modals.disconnected.explanation": "Sunucu bağlantısı kaybedildi", "pad.modals.disconnected.explanation": "Sunucu bağlantısı kaybedildi",
"pad.modals.disconnected.cause": "Sunucu kullanılamıyor olabilir. Bunun devam etmesi durumunda servis yöneticisine bildirin.", "pad.modals.disconnected.cause": "Sunucu kullanılamıyor olabilir. Bunun devam etmesi durumunda servis yöneticisine bildirin.",
"pad.share": "Bu bloknotu paylaş", "pad.share": "Bu bloknotu paylaş",
"pad.share.readonly": "Sadece oku", "pad.share.readonly": "Yalnızca oku",
"pad.share.link": "Bağlantı", "pad.share.link": "Bağlantı",
"pad.share.emebdcode": "URL'yi göm", "pad.share.emebdcode": "URL'yi göm",
"pad.chat": "Sohbet", "pad.chat": "Sohbet",
@ -95,6 +100,7 @@
"pad.chat.loadmessages": "Daha fazla mesaj yükle", "pad.chat.loadmessages": "Daha fazla mesaj yükle",
"pad.chat.stick.title": "Sohbeti ekrana yapıştır", "pad.chat.stick.title": "Sohbeti ekrana yapıştır",
"pad.chat.writeMessage.placeholder": "Mesajını buraya yaz", "pad.chat.writeMessage.placeholder": "Mesajını buraya yaz",
"timeslider.followContents": "Pad içerik güncellemelerini takip edin",
"timeslider.pageTitle": "{{appTitle}} Zaman Çizelgesi", "timeslider.pageTitle": "{{appTitle}} Zaman Çizelgesi",
"timeslider.toolbar.returnbutton": "Bloknota geri dön", "timeslider.toolbar.returnbutton": "Bloknota geri dön",
"timeslider.toolbar.authors": "Yazarlar:", "timeslider.toolbar.authors": "Yazarlar:",

View file

@ -21,7 +21,7 @@
"pad.toolbar.timeslider.title": "Prexentasion storego", "pad.toolbar.timeslider.title": "Prexentasion storego",
"pad.toolbar.savedRevision.title": "Version salvada", "pad.toolbar.savedRevision.title": "Version salvada",
"pad.toolbar.settings.title": "Inpostasion", "pad.toolbar.settings.title": "Inpostasion",
"pad.toolbar.embed.title": "Spartisi e incorpora sto Pad", "pad.toolbar.embed.title": "Spartisi o incastra sto Pad",
"pad.toolbar.showusers.title": "Varda i utenti so sto Pad", "pad.toolbar.showusers.title": "Varda i utenti so sto Pad",
"pad.colorpicker.save": "Salva", "pad.colorpicker.save": "Salva",
"pad.colorpicker.cancel": "Descançełare", "pad.colorpicker.cancel": "Descançełare",

View file

@ -13,11 +13,14 @@
"VulpesVulpes825", "VulpesVulpes825",
"Yfdyh000", "Yfdyh000",
"乌拉跨氪", "乌拉跨氪",
"列维劳德",
"沈澄心",
"燃玉" "燃玉"
] ]
}, },
"index.newPad": "新记事本", "index.newPad": "新记事本",
"index.createOpenPad": "或者创建/打开带名字的记事本:", "index.createOpenPad": "或者创建/打开带名字的记事本:",
"index.openPad": "打开一个现有的记事本,名称为:",
"pad.toolbar.bold.title": "粗体Ctrl-B", "pad.toolbar.bold.title": "粗体Ctrl-B",
"pad.toolbar.italic.title": "斜体Ctrl-I", "pad.toolbar.italic.title": "斜体Ctrl-I",
"pad.toolbar.underline.title": "下划线Ctrl-U", "pad.toolbar.underline.title": "下划线Ctrl-U",
@ -38,7 +41,7 @@
"pad.colorpicker.save": "保存", "pad.colorpicker.save": "保存",
"pad.colorpicker.cancel": "取消", "pad.colorpicker.cancel": "取消",
"pad.loading": "载入中……", "pad.loading": "载入中……",
"pad.noCookie": "无法找到Cookie。请在您的浏览器中允许Cookie", "pad.noCookie": "无法找到Cookie。请在您的浏览器中允许Cookie您的会话和设置不会在访问时保存。这可能是由于Etherpad包含在某些浏览器中的iFrame中。请确保Etherpad与父iFrame位于同一子域/域上",
"pad.passwordRequired": "您需要密码才能访问这个记事本", "pad.passwordRequired": "您需要密码才能访问这个记事本",
"pad.permissionDenied": "您没有访问这个记事本的权限", "pad.permissionDenied": "您没有访问这个记事本的权限",
"pad.wrongPassword": "您的密码错了", "pad.wrongPassword": "您的密码错了",
@ -52,6 +55,8 @@
"pad.settings.fontType": "字体类型:", "pad.settings.fontType": "字体类型:",
"pad.settings.fontType.normal": "正常", "pad.settings.fontType.normal": "正常",
"pad.settings.language": "语言:", "pad.settings.language": "语言:",
"pad.settings.about": "关于",
"pad.settings.poweredBy": "技术支持来自",
"pad.importExport.import_export": "导入/导出", "pad.importExport.import_export": "导入/导出",
"pad.importExport.import": "上载任何文本文件或档案", "pad.importExport.import": "上载任何文本文件或档案",
"pad.importExport.importSuccessful": "成功!", "pad.importExport.importSuccessful": "成功!",
@ -62,7 +67,7 @@
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF开放文档格式", "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-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 或是 LibreOffice</a>。",
"pad.modals.connected": "已连接。", "pad.modals.connected": "已连接。",
"pad.modals.reconnecting": "重新连接到您的记事本...", "pad.modals.reconnecting": "重新连接到您的记事本...",
"pad.modals.forcereconnect": "强制重新连接", "pad.modals.forcereconnect": "强制重新连接",
@ -86,6 +91,8 @@
"pad.modals.corruptPad.cause": "这可能是因为服务器配置的错误或者其他未预料到的行为。请联系服务管理员。", "pad.modals.corruptPad.cause": "这可能是因为服务器配置的错误或者其他未预料到的行为。请联系服务管理员。",
"pad.modals.deleted": "已删除。", "pad.modals.deleted": "已删除。",
"pad.modals.deleted.explanation": "此记事本已被移除。", "pad.modals.deleted.explanation": "此记事本已被移除。",
"pad.modals.rateLimited": "速率限制",
"pad.modals.rateLimited.explanation": "您向此记事本发送了太多消息,因此中断了与您的连接。",
"pad.modals.disconnected": "您已断开连接。", "pad.modals.disconnected": "您已断开连接。",
"pad.modals.disconnected.explanation": "到服务器的连接已丢失", "pad.modals.disconnected.explanation": "到服务器的连接已丢失",
"pad.modals.disconnected.cause": "服务器可能无法使用。若此情况持续发生,请通知服务器管理员。", "pad.modals.disconnected.cause": "服务器可能无法使用。若此情况持续发生,请通知服务器管理员。",
@ -98,6 +105,7 @@
"pad.chat.loadmessages": "加载更多信息", "pad.chat.loadmessages": "加载更多信息",
"pad.chat.stick.title": "在屏幕上固定聊天界面", "pad.chat.stick.title": "在屏幕上固定聊天界面",
"pad.chat.writeMessage.placeholder": "在此写下您的消息", "pad.chat.writeMessage.placeholder": "在此写下您的消息",
"timeslider.followContents": "跟随记事本的内容更新",
"timeslider.pageTitle": "{{appTitle}} 时间轴", "timeslider.pageTitle": "{{appTitle}} 时间轴",
"timeslider.toolbar.returnbutton": "返回记事本", "timeslider.toolbar.returnbutton": "返回记事本",
"timeslider.toolbar.authors": "作者:", "timeslider.toolbar.authors": "作者:",
@ -130,7 +138,7 @@
"pad.userlist.guest": "访客", "pad.userlist.guest": "访客",
"pad.userlist.deny": "拒绝", "pad.userlist.deny": "拒绝",
"pad.userlist.approve": "批准", "pad.userlist.approve": "批准",
"pad.editbar.clearcolors": "清除整个文档的作者颜色吗?", "pad.editbar.clearcolors": "清除整个文档的作者颜色吗?此操作无法撤消",
"pad.impexp.importbutton": "现在导入", "pad.impexp.importbutton": "现在导入",
"pad.impexp.importing": "正在导入...", "pad.impexp.importing": "正在导入...",
"pad.impexp.confirmimport": "导入的文件将覆盖记事本的当前文本。你确定要继续吗?", "pad.impexp.confirmimport": "导入的文件将覆盖记事本的当前文本。你确定要继续吗?",
@ -139,5 +147,7 @@
"pad.impexp.uploadFailed": "上载失败,请重试", "pad.impexp.uploadFailed": "上载失败,请重试",
"pad.impexp.importfailed": "导入失败", "pad.impexp.importfailed": "导入失败",
"pad.impexp.copypaste": "请复制粘贴", "pad.impexp.copypaste": "请复制粘贴",
"pad.impexp.exportdisabled": "{{type}} 格式的导出被禁用。有关详情,请与您的系统管理员联系。" "pad.impexp.exportdisabled": "{{type}} 格式的导出被禁用。有关详情,请与您的系统管理员联系。",
"pad.impexp.maxFileSize": "文件太大。 请与您的站点管理员联系以增加允许导入的文件大小",
"pad.impexp.permission": "因为你从未为在此记事本做出任何贡献,导入已被禁用。在导入之前,请至少贡献一次"
} }

View file

@ -14,6 +14,7 @@
}, },
"index.newPad": "新記事本", "index.newPad": "新記事本",
"index.createOpenPad": "或建立/開啟以下名稱的記事本:", "index.createOpenPad": "或建立/開啟以下名稱的記事本:",
"index.openPad": "開啟一個現有的記事本,名稱為:",
"pad.toolbar.bold.title": "粗體Ctrl+B", "pad.toolbar.bold.title": "粗體Ctrl+B",
"pad.toolbar.italic.title": "斜體Ctrl+I", "pad.toolbar.italic.title": "斜體Ctrl+I",
"pad.toolbar.underline.title": "底線Ctrl+U", "pad.toolbar.underline.title": "底線Ctrl+U",
@ -34,7 +35,7 @@
"pad.colorpicker.save": "儲存", "pad.colorpicker.save": "儲存",
"pad.colorpicker.cancel": "取消", "pad.colorpicker.cancel": "取消",
"pad.loading": "載入中...", "pad.loading": "載入中...",
"pad.noCookie": "找不到 Cookie。請允許瀏覽器使用 Cookie", "pad.noCookie": "找不到 Cookie。請允許瀏覽器使用 Cookie您的 session 與設定沒有在訪問期間被儲存下來,這可能是因為在某些瀏覽器裡 Etherpad 被包在 iFrame 中,請確認 Etherpad 是在父層級的 iFrame 相同的網域/子網域。",
"pad.passwordRequired": "您需要密碼才能存取這個記事本", "pad.passwordRequired": "您需要密碼才能存取這個記事本",
"pad.permissionDenied": "你沒有存取這個記事本的權限", "pad.permissionDenied": "你沒有存取這個記事本的權限",
"pad.wrongPassword": "密碼錯誤", "pad.wrongPassword": "密碼錯誤",
@ -48,6 +49,8 @@
"pad.settings.fontType": "字型類型:", "pad.settings.fontType": "字型類型:",
"pad.settings.fontType.normal": "正常", "pad.settings.fontType.normal": "正常",
"pad.settings.language": "語言:", "pad.settings.language": "語言:",
"pad.settings.about": "關於",
"pad.settings.poweredBy": "技術提供來自",
"pad.importExport.import_export": "匯入/匯出", "pad.importExport.import_export": "匯入/匯出",
"pad.importExport.import": "上載任何文字檔或文件", "pad.importExport.import": "上載任何文字檔或文件",
"pad.importExport.importSuccessful": "完成!", "pad.importExport.importSuccessful": "完成!",
@ -82,6 +85,8 @@
"pad.modals.corruptPad.cause": "這可能由於伺服器的配置錯誤或遇到意外問題。請聯繫伺服器管理員。", "pad.modals.corruptPad.cause": "這可能由於伺服器的配置錯誤或遇到意外問題。請聯繫伺服器管理員。",
"pad.modals.deleted": "已刪除。", "pad.modals.deleted": "已刪除。",
"pad.modals.deleted.explanation": "此記事本已被移除。", "pad.modals.deleted.explanation": "此記事本已被移除。",
"pad.modals.rateLimited": "比例限制。",
"pad.modals.rateLimited.explanation": "您發送太多訊息到此記事本,因此中斷了您的連結。",
"pad.modals.disconnected": "您已中斷連線。", "pad.modals.disconnected": "您已中斷連線。",
"pad.modals.disconnected.explanation": "伺服器連接曾中斷", "pad.modals.disconnected.explanation": "伺服器連接曾中斷",
"pad.modals.disconnected.cause": "伺服器可能無法使用。若此情況持續發生,請通知伺服器管理員。", "pad.modals.disconnected.cause": "伺服器可能無法使用。若此情況持續發生,請通知伺服器管理員。",
@ -94,6 +99,7 @@
"pad.chat.loadmessages": "載入更多訊息", "pad.chat.loadmessages": "載入更多訊息",
"pad.chat.stick.title": "釘住聊天在螢幕上", "pad.chat.stick.title": "釘住聊天在螢幕上",
"pad.chat.writeMessage.placeholder": "在此編寫您的訊息", "pad.chat.writeMessage.placeholder": "在此編寫您的訊息",
"timeslider.followContents": "關注記事本內容更新",
"timeslider.pageTitle": "{{appTitle}}時間軸", "timeslider.pageTitle": "{{appTitle}}時間軸",
"timeslider.toolbar.returnbutton": "返回到記事本", "timeslider.toolbar.returnbutton": "返回到記事本",
"timeslider.toolbar.authors": "協作者:", "timeslider.toolbar.authors": "協作者:",

View file

@ -50,7 +50,7 @@ exports.deleteGroup = async function(groupID)
// iterate through group2sessions and delete all sessions // iterate through group2sessions and delete all sessions
let group2sessions = await db.get("group2sessions:" + groupID); let group2sessions = await db.get("group2sessions:" + groupID);
let sessions = group2sessions ? group2sessions.sessionsIDs : {}; let sessions = group2sessions ? group2sessions.sessionIDs : {};
// loop through all sessions and delete them (in parallel) // loop through all sessions and delete them (in parallel)
await Promise.all(Object.keys(sessions).map(session => { await Promise.all(Object.keys(sessions).map(session => {

View file

@ -93,6 +93,7 @@ Pad.prototype.appendRevision = function appendRevision(aChangeset, author) {
} }
if (newRev % 100 == 0) { if (newRev % 100 == 0) {
newRevData.meta.pool = this.pool;
newRevData.meta.atext = this.atext; newRevData.meta.atext = this.atext;
} }

View file

@ -26,30 +26,41 @@ var settings = require("../utils/Settings");
var log4js = require('log4js'); var log4js = require('log4js');
var authLogger = log4js.getLogger("auth"); var authLogger = log4js.getLogger("auth");
const DENY = Object.freeze({accessStatus: 'deny'});
const WRONG_PASSWORD = Object.freeze({accessStatus: 'wrongPassword'});
const NEED_PASSWORD = Object.freeze({accessStatus: 'needPassword'});
/** /**
* This function controlls the access to a pad, it checks if the user can access a pad. * Determines whether the user can access a pad.
* @param padID the pad the user wants to access *
* @param sessionCookie the session the user has (set via api) * @param padID identifies the pad the user wants to access.
* @param token a random token representing the author, of the form * @param sessionCookie identifies the sessions the user created via the HTTP API, if any.
* t.randomstring_of_lenght_20. The random string is generated by * Note: The term "session" used here is unrelated to express-session.
* the client. * @param token is a random token of the form t.randomstring_of_length_20 generated by the client
* Used for every pad in the web UI. Not used for the HTTP API. * when using the web UI (not the HTTP API). This token is only used if settings.requireSession
* @param password the password the user has given to access this pad, can be null * is false and the user is accessing a public pad. If there is not an author already associated
* @return {accessStatus: grant|deny|wrongPassword|needPassword, authorID: a.xxxxxx}) * with this token then a new author object is created (including generating an author ID) and
* associated with this token.
* @param password is the password the user has given to access this pad. It can be null.
* @return {accessStatus: grant|deny|wrongPassword|needPassword, authorID: a.xxxxxx}. The caller
* must use the author ID returned in this object when making any changes associated with the
* author.
*
* WARNING: Tokens and session IDs MUST be kept secret, otherwise users will be able to impersonate
* each other (which might allow them to gain privileges).
*
* TODO: Add a hook so that plugins can make access decisions.
*/ */
exports.checkAccess = async function(padID, sessionCookie, token, password) exports.checkAccess = async function(padID, sessionCookie, token, password)
{ {
// immutable object
let deny = Object.freeze({ accessStatus: "deny" });
if (!padID) { if (!padID) {
return deny; return DENY;
} }
// allow plugins to deny access // allow plugins to deny access
var deniedByHook = hooks.callAll("onAccessCheck", {'padID': padID, 'password': password, 'token': token, 'sessionCookie': sessionCookie}).indexOf(false) > -1; var deniedByHook = hooks.callAll("onAccessCheck", {'padID': padID, 'password': password, 'token': token, 'sessionCookie': sessionCookie}).indexOf(false) > -1;
if (deniedByHook) { if (deniedByHook) {
return deny; return DENY;
} }
// start to get author for this token // start to get author for this token
@ -62,31 +73,14 @@ exports.checkAccess = async function(padID, sessionCookie, token, password)
// a valid session is required (api-only mode) // a valid session is required (api-only mode)
if (!sessionCookie) { if (!sessionCookie) {
// without sessionCookie, access is denied // without sessionCookie, access is denied
return deny; return DENY;
} }
} else { } else {
// a session is not required, so we'll check if it's a public pad // a session is not required, so we'll check if it's a public pad
if (padID.indexOf("$") === -1) { if (padID.indexOf("$") === -1) {
// it's not a group pad, means we can grant access // it's not a group pad, means we can grant access
if (settings.editOnly && !(await p_padExists)) return DENY;
// assume user has access return {accessStatus: 'grant', authorID: await p_tokenAuthor};
let authorID = await p_tokenAuthor;
let statusObject = { accessStatus: "grant", authorID };
if (settings.editOnly) {
// user can't create pads
let padExists = await p_padExists;
if (!padExists) {
// pad doesn't exist - user can't have access
statusObject.accessStatus = "deny";
}
}
// user may create new pads - no need to check anything
// grant access, with author of token
return statusObject;
} }
} }
@ -207,14 +201,14 @@ exports.checkAccess = async function(padID, sessionCookie, token, password)
// - the pad is password protected but wrong password given // - the pad is password protected but wrong password given
// --> deny access, ask for new password and tell them that the password is wrong // --> deny access, ask for new password and tell them that the password is wrong
return { accessStatus: "wrongPassword" }; return WRONG_PASSWORD;
} }
if (isPasswordProtected && passwordStatus === "notGiven") { if (isPasswordProtected && passwordStatus === "notGiven") {
// - the pad is password protected but no password given // - the pad is password protected but no password given
// --> ask for password // --> ask for password
return { accessStatus: "needPassword" }; return NEED_PASSWORD;
} }
throw new Error("Oops, something wrong happend"); throw new Error("Oops, something wrong happend");
@ -230,7 +224,7 @@ exports.checkAccess = async function(padID, sessionCookie, token, password)
// --> deny access if user isn't allowed to create the pad // --> deny access if user isn't allowed to create the pad
if (settings.editOnly) { if (settings.editOnly) {
authLogger.debug("Auth failed: valid session & pad does not exist"); authLogger.debug("Auth failed: valid session & pad does not exist");
accessStatus = "deny"; return DENY;
} }
return { accessStatus, authorID }; return { accessStatus, authorID };
@ -260,14 +254,14 @@ exports.checkAccess = async function(padID, sessionCookie, token, password)
// - it's public and the pad is password protected but wrong password given // - it's public and the pad is password protected but wrong password given
// --> deny access, ask for new password and tell them that the password is wrong // --> deny access, ask for new password and tell them that the password is wrong
return { accessStatus: "wrongPassword" }; return WRONG_PASSWORD;
} }
if (isPublic && isPasswordProtected && passwordStatus === "notGiven") { if (isPublic && isPasswordProtected && passwordStatus === "notGiven") {
// - it's public and the pad is password protected but no password given // - it's public and the pad is password protected but no password given
// --> ask for password // --> ask for password
return { accessStatus: "needPassword" }; return NEED_PASSWORD;
} }
if (!isPublic) { if (!isPublic) {
@ -275,7 +269,7 @@ exports.checkAccess = async function(padID, sessionCookie, token, password)
authLogger.debug("Auth failed: invalid session & pad is not public"); authLogger.debug("Auth failed: invalid session & pad is not public");
// --> deny access // --> deny access
return { accessStatus: "deny" }; return DENY;
} }
throw new Error("Oops, something wrong happend"); throw new Error("Oops, something wrong happend");
@ -283,5 +277,5 @@ exports.checkAccess = async function(padID, sessionCookie, token, password)
// there is no valid session avaiable AND pad doesn't exist // there is no valid session avaiable AND pad doesn't exist
authLogger.debug("Auth failed: invalid session & pad does not exist"); authLogger.debug("Auth failed: invalid session & pad does not exist");
return { accessStatus: "deny" }; return DENY;
} }

View file

@ -24,6 +24,9 @@ var fs = require("fs");
var path = require("path"); var path = require("path");
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks.js"); var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks.js");
var resolve = require("resolve"); var resolve = require("resolve");
var settings = require('../utils/Settings');
const templateCache = new Map()
exports.info = { exports.info = {
__output_stack: [], __output_stack: [],
@ -114,12 +117,26 @@ exports.require = function (name, args, mod) {
args.e = exports; args.e = exports;
args.require = require; args.require = require;
var template = '<% e._init(__output); %>' + fs.readFileSync(ejspath).toString() + '<% e._exit(); %>';
let template
if (settings.maxAge !== 0){ // don't cache if maxAge is 0
if (!templateCache.has(ejspath)) {
template = '<% e._init(__output); %>' + fs.readFileSync(ejspath).toString() + '<% e._exit(); %>';
templateCache.set(ejspath, template)
} else {
template = templateCache.get(ejspath)
}
}else{
template = '<% e._init(__output); %>' + fs.readFileSync(ejspath).toString() + '<% e._exit(); %>';
}
exports.info.args.push(args); exports.info.args.push(args);
exports.info.file_stack.push({path: ejspath, inherit: []}); exports.info.file_stack.push({path: ejspath, inherit: []});
if(settings.maxAge !== 0){
var res = ejs.render(template, args); var res = ejs.render(template, args, { cache: true, filename: ejspath });
}else{
var res = ejs.render(template, args, { cache: false, filename: ejspath });
}
exports.info.file_stack.pop(); exports.info.file_stack.pop();
exports.info.args.pop(); exports.info.args.pop();

View file

@ -74,6 +74,18 @@ async function doImport(req, res, padId)
form.uploadDir = tmpDirectory; form.uploadDir = tmpDirectory;
form.maxFileSize = settings.importMaxFileSize; form.maxFileSize = settings.importMaxFileSize;
// Ref: https://github.com/node-formidable/formidable/issues/469
// Crash in Etherpad was Uploading Error: Error: Request aborted
// [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed
form.onPart = part => {
form.handlePart(part);
if (part.filename !== undefined) {
form.openedFiles[form.openedFiles.length - 1]._writeStream.on('error', err => {
form.emit('error', err);
});
}
};
// locally wrapped Promise, since form.parse requires a callback // locally wrapped Promise, since form.parse requires a callback
let srcFile = await new Promise((resolve, reject) => { let srcFile = await new Promise((resolve, reject) => {
form.parse(req, function(err, fields, files) { form.parse(req, function(err, fields, files) {
@ -84,7 +96,7 @@ async function doImport(req, res, padId)
} }
// I hate doing indexOf here but I can't see anything to use... // I hate doing indexOf here but I can't see anything to use...
if (err.stack.indexOf("maxFileSize") !== -1) { if (err && err.stack && err.stack.indexOf("maxFileSize") !== -1) {
reject("maxFileSize"); reject("maxFileSize");
} }
@ -274,15 +286,6 @@ exports.doImport = function (req, res, padId)
} }
}).then(() => { }).then(() => {
// close the connection // close the connection
res.send( res.send("<script>document.addEventListener('DOMContentLoaded', function(){ var impexp = window.parent.padimpexp.handleFrameCall('" + req.directDatabaseAccess +"', '" + status + "'); })</script>");
"<head> \
<script type='text/javascript' src='../../static/js/jquery.js'></script> \
</head> \
<script> \
$(window).load(function(){ \
var impexp = window.parent.padimpexp.handleFrameCall('" + req.directDatabaseAccess +"', '" + status + "'); \
}) \
</script>"
);
}); });
} }

View file

@ -27,7 +27,7 @@ var authorManager = require("../db/AuthorManager");
var readOnlyManager = require("../db/ReadOnlyManager"); var readOnlyManager = require("../db/ReadOnlyManager");
var settings = require('../utils/Settings'); var settings = require('../utils/Settings');
var securityManager = require("../db/SecurityManager"); var securityManager = require("../db/SecurityManager");
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins.js"); var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugin_defs.js");
var log4js = require('log4js'); var log4js = require('log4js');
var messageLogger = log4js.getLogger("message"); var messageLogger = log4js.getLogger("message");
var accessLogger = log4js.getLogger("access"); var accessLogger = log4js.getLogger("access");
@ -36,7 +36,14 @@ var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks.js");
var channels = require("channels"); var channels = require("channels");
var stats = require('../stats'); var stats = require('../stats');
var remoteAddress = require("../utils/RemoteAddress").remoteAddress; var remoteAddress = require("../utils/RemoteAddress").remoteAddress;
const assert = require('assert').strict;
const nodeify = require("nodeify"); const nodeify = require("nodeify");
const { RateLimiterMemory } = require('rate-limiter-flexible');
const rateLimiter = new RateLimiterMemory({
points: settings.commitRateLimiting.points,
duration: settings.commitRateLimiting.duration
});
/** /**
* A associative array that saves informations about a session * A associative array that saves informations about a session
@ -164,6 +171,19 @@ exports.handleDisconnect = async function(client)
*/ */
exports.handleMessage = async function(client, message) exports.handleMessage = async function(client, message)
{ {
var env = process.env.NODE_ENV || 'development';
if (env === 'production') {
try {
await rateLimiter.consume(client.handshake.address); // consume 1 point per event from IP
}catch(e){
console.warn("Rate limited: ", client.handshake.address, " to reduce the amount of rate limiting that happens edit the rateLimit values in settings.json");
stats.meter('rateLimited').mark();
client.json.send({disconnect:"rateLimited"});
return;
}
}
if (message == null) { if (message == null) {
return; return;
} }
@ -239,35 +259,13 @@ exports.handleMessage = async function(client, message)
} }
} }
/*
* In a previous version of this code, an "if (message)" wrapped the
* following series of async calls [now replaced with await calls]
* This ugly "!Boolean(message)" is a lame way to exactly negate the truthy
* condition and replace it with an early return, while being sure to leave
* the original behaviour unchanged.
*
* A shallower code could maybe make more evident latent logic errors.
*/
if (!Boolean(message)) {
return;
}
let dropMessage = await handleMessageHook(); let dropMessage = await handleMessageHook();
if (!dropMessage) { if (!dropMessage) {
// check permissions
if (message.type == "CLIENT_READY") { if (message.type == "CLIENT_READY") {
// client tried to auth for the first time (first msg from the client) // client tried to auth for the first time (first msg from the client)
createSessionInfo(client, message); createSessionInfo(client, message);
} }
// Note: message.sessionID is an entirely different kind of
// session from the sessions we use here! Beware!
// FIXME: Call our "sessions" "connections".
// FIXME: Use a hook instead
// FIXME: Allow to override readwrite access with readonly
// the session may have been dropped during earlier processing // the session may have been dropped during earlier processing
if (!sessioninfos[client.id]) { if (!sessioninfos[client.id]) {
messageLogger.warn("Dropping message from a connection that has gone away.") messageLogger.warn("Dropping message from a connection that has gone away.")
@ -895,12 +893,6 @@ async function handleClientReady(client, message)
// Get ro/rw id:s // Get ro/rw id:s
let padIds = await readOnlyManager.getIds(message.padId); let padIds = await readOnlyManager.getIds(message.padId);
// check permissions
// Note: message.sessionID is an entierly different kind of
// session from the sessions we use here! Beware!
// FIXME: Call our "sessions" "connections".
// FIXME: Use a hook instead
// FIXME: Allow to override readwrite access with readonly // FIXME: Allow to override readwrite access with readonly
let statusObject = await securityManager.checkAccess(padIds.padId, message.sessionID, message.token, message.password); let statusObject = await securityManager.checkAccess(padIds.padId, message.sessionID, message.token, message.password);
let accessStatus = statusObject.accessStatus; let accessStatus = statusObject.accessStatus;
@ -914,6 +906,7 @@ async function handleClientReady(client, message)
let author = statusObject.authorID; let author = statusObject.authorID;
// get all authordata of this new user // get all authordata of this new user
assert(author);
let value = await authorManager.getAuthor(author); let value = await authorManager.getAuthor(author);
let authorColorId = value.colorId; let authorColorId = value.colorId;
let authorName = value.name; let authorName = value.name;
@ -1131,6 +1124,7 @@ async function handleClientReady(client, message)
}, },
"initialChangesets": [], // FIXME: REMOVE THIS SHIT "initialChangesets": [], // FIXME: REMOVE THIS SHIT
"thisUserHasEditedThisPad": thisUserHasEditedThisPad, "thisUserHasEditedThisPad": thisUserHasEditedThisPad,
"allowAnyoneToImport": settings.allowAnyoneToImport
} }
// Add a username to the clientVars if one avaiable // Add a username to the clientVars if one avaiable
@ -1139,7 +1133,7 @@ async function handleClientReady(client, message)
} }
// call the clientVars-hook so plugins can modify them before they get sent to the client // call the clientVars-hook so plugins can modify them before they get sent to the client
let messages = await hooks.aCallAll("clientVars", { clientVars: clientVars, pad: pad }); let messages = await hooks.aCallAll('clientVars', {clientVars, pad, socket: client});
// combine our old object with the new attributes from the hook // combine our old object with the new attributes from the hook
for (let msg of messages) { for (let msg of messages) {
@ -1294,7 +1288,7 @@ async function handleChangesetRequest(client, message)
data.requestID = message.data.requestID; data.requestID = message.data.requestID;
client.json.send({ type: "CHANGESET_REQ", data }); client.json.send({ type: "CHANGESET_REQ", data });
} catch (err) { } catch (err) {
console.error('Error while handling a changeset request for ' + padIds.padId, err, message.data); console.error('Error while handling a changeset request for ' + padIds.padId, err.toString(), message.data);
} }
} }
@ -1495,8 +1489,12 @@ exports.padUsers = async function(padID) {
let s = sessioninfos[roomClient.id]; let s = sessioninfos[roomClient.id];
if (s) { if (s) {
return authorManager.getAuthor(s.author).then(author => { return authorManager.getAuthor(s.author).then(author => {
author.id = s.author; // Fixes: https://github.com/ether/etherpad-lite/issues/4120
padUsers.push(author); // On restart author might not be populated?
if(author){
author.id = s.author;
padUsers.push(author);
}
}); });
} }
})); }));

View file

@ -1,13 +1,13 @@
var eejs = require('ep_etherpad-lite/node/eejs'); var eejs = require('ep_etherpad-lite/node/eejs');
var settings = require('ep_etherpad-lite/node/utils/Settings'); var settings = require('ep_etherpad-lite/node/utils/Settings');
var installer = require('ep_etherpad-lite/static/js/pluginfw/installer'); var installer = require('ep_etherpad-lite/static/js/pluginfw/installer');
var plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins'); var plugins = require('ep_etherpad-lite/static/js/pluginfw/plugin_defs');
var _ = require('underscore'); var _ = require('underscore');
var semver = require('semver'); var semver = require('semver');
const UpdateCheck = require('ep_etherpad-lite/node/utils/UpdateCheck');
exports.expressCreateServer = function(hook_name, args, cb) { exports.expressCreateServer = function(hook_name, args, cb) {
args.app.get('/admin/plugins', function(req, res) { args.app.get('/admin/plugins', function(req, res) {
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins");
var render_args = { var render_args = {
plugins: plugins.plugins, plugins: plugins.plugins,
search_results: {}, search_results: {},
@ -23,7 +23,8 @@ exports.expressCreateServer = function(hook_name, args, cb) {
res.send(eejs.require("ep_etherpad-lite/templates/admin/plugins-info.html", { res.send(eejs.require("ep_etherpad-lite/templates/admin/plugins-info.html", {
gitCommit: gitCommit, gitCommit: gitCommit,
epVersion: epVersion epVersion: epVersion,
latestVersion: UpdateCheck.getLatestVersion()
})); }));
}); });
} }

View file

@ -29,9 +29,9 @@ exports.socketio = function (hook_name, args, cb) {
return console.log(err); return console.log(err);
} }
//if showSettingsInAdminPage is set to false, then return NOT_ALLOWED in the result // if showSettingsInAdminPage is set to false, then return NOT_ALLOWED in the result
if(settings.showSettingsInAdminPage === false) { if(settings.showSettingsInAdminPage === false) {
socket.emit("settings", {results:'NOT_ALLOWED'}); socket.emit("settings", {results: 'NOT_ALLOWED'});
} }
else { else {
socket.emit("settings", {results: data}); socket.emit("settings", {results: data});

View file

@ -1,3 +1,4 @@
const assert = require('assert').strict;
var hasPadAccess = require("../../padaccess"); var hasPadAccess = require("../../padaccess");
var settings = require('../../utils/Settings'); var settings = require('../../utils/Settings');
var exportHandler = require('../../handler/ExportHandler'); var exportHandler = require('../../handler/ExportHandler');
@ -5,6 +6,7 @@ var importHandler = require('../../handler/ImportHandler');
var padManager = require("../../db/PadManager"); var padManager = require("../../db/PadManager");
var authorManager = require("../../db/AuthorManager"); var authorManager = require("../../db/AuthorManager");
const rateLimit = require("express-rate-limit"); const rateLimit = require("express-rate-limit");
const securityManager = require("../../db/SecurityManager");
settings.importExportRateLimiting.onLimitReached = function(req, res, options) { settings.importExportRateLimiting.onLimitReached = function(req, res, options) {
// when the rate limiter triggers, write a warning in the logs // when the rate limiter triggers, write a warning in the logs
@ -51,57 +53,41 @@ exports.expressCreateServer = function (hook_name, args, cb) {
// handle import requests // handle import requests
args.app.use('/p/:pad/import', limiter); args.app.use('/p/:pad/import', limiter);
args.app.post('/p/:pad/import', async function(req, res, next) { args.app.post('/p/:pad/import', async function(req, res, next) {
if (await hasPadAccess(req, res)) { if (!(await padManager.doesPadExists(req.params.pad))) {
let exists = await padManager.doesPadExists(req.params.pad); console.warn(`Someone tried to import into a pad that doesn't exist (${req.params.pad})`);
if (!exists) { return next();
console.warn(`Someone tried to import into a pad that doesn't exist (${req.params.pad})`);
return next();
}
/*
* Starting from Etherpad 1.8.3 onwards, importing into a pad is allowed
* only if a user has his browser opened and connected to the pad (i.e. a
* Socket.IO session is estabilished for him) and he has already
* contributed to that specific pad.
*
* Note that this does not have anything to do with the "session", used
* for logging into "group pads". That kind of session is not needed here.
*
* This behaviour does not apply to API requests, only to /p/$PAD$/import
*
* See: https://github.com/ether/etherpad-lite/pull/3833#discussion_r407490205
*/
if (!req.cookies) {
console.warn(`Unable to import file into "${req.params.pad}". No cookies included in request`);
return next();
}
if (!req.cookies.token) {
console.warn(`Unable to import file into "${req.params.pad}". No token in the cookies`);
return next();
}
let author = await authorManager.getAuthor4Token(req.cookies.token);
// author is of the form: "a.g2droBYw1prY7HW9"
if (!author) {
console.warn(`Unable to import file into "${req.params.pad}". No Author found for token ${req.cookies.token}`);
return next();
}
let authorsPads = await authorManager.listPadsOfAuthor(author);
if (!authorsPads) {
console.warn(`Unable to import file into "${req.params.pad}". Author "${author}" exists but he never contributed to any pad`);
return next();
}
let authorsPadIDs = authorsPads.padIDs;
if (authorsPadIDs.indexOf(req.params.pad) === -1) {
console.warn(`Unable to import file into "${req.params.pad}". Author "${author}" exists but he never contributed to this pad`);
return next();
}
importHandler.doImport(req, res, req.params.pad);
} }
const {accessStatus, authorID} = await securityManager.checkAccess(
req.params.pad, req.cookies.sessionID, req.cookies.token, req.cookies.password);
if (accessStatus !== 'grant') return res.status(403).send('Forbidden');
assert(authorID);
/*
* Starting from Etherpad 1.8.3 onwards, importing into a pad is allowed
* only if a user has his browser opened and connected to the pad (i.e. a
* Socket.IO session is estabilished for him) and he has already
* contributed to that specific pad.
*
* Note that this does not have anything to do with the "session", used
* for logging into "group pads". That kind of session is not needed here.
*
* This behaviour does not apply to API requests, only to /p/$PAD$/import
*
* See: https://github.com/ether/etherpad-lite/pull/3833#discussion_r407490205
*/
if (!settings.allowAnyoneToImport) {
const authorsPads = await authorManager.listPadsOfAuthor(authorID);
if (!authorsPads) {
console.warn(`Unable to import file into "${req.params.pad}". Author "${authorID}" exists but he never contributed to any pad`);
return next();
}
if (authorsPads.padIDs.indexOf(req.params.pad) === -1) {
console.warn(`Unable to import file into "${req.params.pad}". Author "${authorID}" exists but he never contributed to this pad`);
return next();
}
}
importHandler.doImport(req, res, req.params.pad);
}); });
} }

View file

@ -688,7 +688,7 @@ exports.expressCreateServer = async (_, args) => {
// support jsonp response format // support jsonp response format
if (req.query.jsonp && isValidJSONPName.check(req.query.jsonp)) { if (req.query.jsonp && isValidJSONPName.check(req.query.jsonp)) {
res.header('Content-Type', 'application/javascript'); res.header('Content-Type', 'application/javascript');
response = `${req.query.jsonp}(${JSON.stringify(response)}`; response = `${req.query.jsonp}(${JSON.stringify(response)})`;
} }
// send response // send response

View file

@ -47,25 +47,35 @@ exports.expressCreateServer = function (hook_name, args, cb) {
io.use(function(socket, accept) { io.use(function(socket, accept) {
var data = socket.request; var data = socket.request;
// Use a setting if we want to allow load Testing // Use a setting if we want to allow load Testing
if(!data.headers.cookie && settings.loadTest){
// Sometimes browsers might not have cookies at all, for example Safari in iFrames Cross domain
// https://github.com/ether/etherpad-lite/issues/4031
// if requireSession is false we can allow them to still get on the pad.
// Note that this does make security less tight because any socketIO connection can be established without
// any logic on the client to do any handshaking.. I am not concerned about this though, the real solution
// here is to implement rateLimiting on SocketIO ACCEPT_COMMIT messages.
if(!data.headers.cookie && (settings.loadTest || !settings.requireSession)){
accept(null, true); accept(null, true);
}else{ }else{
if (!data.headers.cookie) return accept('No session cookie transmitted.', false); if (!data.headers.cookie) return accept('No session cookie transmitted.', false);
} }
cookieParserFn(data, {}, function(err){ if(data.headers.cookie){
if(err) { cookieParserFn(data, {}, function(err){
console.error(err); if(err) {
accept("Couldn't parse request cookies. ", false); console.error(err);
return; accept("Couldn't parse request cookies. ", false);
} return;
}
data.sessionID = data.signedCookies.express_sid; data.sessionID = data.signedCookies.express_sid;
args.app.sessionStore.get(data.sessionID, function (err, session) { args.app.sessionStore.get(data.sessionID, function (err, session) {
if (err || !session) return accept('Bad session / session has expired', false); if (err || !session) return accept('Bad session / session has expired', false);
data.session = new sessionModule.Session(data, session); data.session = new sessionModule.Session(data, session);
accept(null, true); accept(null, true);
});
}); });
}); }
}); });
// var socketIOLogger = log4js.getLogger("socket.io"); // var socketIOLogger = log4js.getLogger("socket.io");

View file

@ -29,7 +29,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
var filePath = path.join(settings.root, "src", "static", "skins", settings.skinName, "robots.txt"); var filePath = path.join(settings.root, "src", "static", "skins", settings.skinName, "robots.txt");
res.sendFile(filePath, function(err) res.sendFile(filePath, function(err)
{ {
//there is no custom favicon, send the default robots.txt which dissallows all //there is no custom robots.txt, send the default robots.txt which dissallows all
if(err) if(err)
{ {
filePath = path.join(settings.root, "src", "static", "robots.txt"); filePath = path.join(settings.root, "src", "static", "robots.txt");

View file

@ -1,5 +1,5 @@
var minify = require('../../utils/Minify'); var minify = require('../../utils/Minify');
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins"); var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugin_defs");
var CachingMiddleware = require('../../utils/caching_middleware'); var CachingMiddleware = require('../../utils/caching_middleware');
var settings = require("../../utils/Settings"); var settings = require("../../utils/Settings");
var Yajsml = require('etherpad-yajsml'); var Yajsml = require('etherpad-yajsml');

View file

@ -17,7 +17,8 @@ exports.expressCreateServer = function (hook_name, args, cb) {
files = files.filter(el => !/\.swp$/.test(el)) files = files.filter(el => !/\.swp$/.test(el))
console.debug("Sent browser the following test specs:", files); console.debug("Sent browser the following test specs:", files);
res.send("var specs_list = " + JSON.stringify(files) + ";\n"); res.setHeader('content-type', 'text/javascript');
res.end("var specs_list = " + JSON.stringify(files) + ";\n");
}); });
// path.join seems to normalize by default, but we'll just be explicit // path.join seems to normalize by default, but we'll just be explicit

View file

@ -1,116 +1,131 @@
var express = require('express'); const express = require('express');
var log4js = require('log4js'); const log4js = require('log4js');
var httpLogger = log4js.getLogger("http"); const httpLogger = log4js.getLogger('http');
var settings = require('../../utils/Settings'); const settings = require('../../utils/Settings');
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks'); const hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
var ueberStore = require('../../db/SessionStore'); const ueberStore = require('../../db/SessionStore');
var stats = require('ep_etherpad-lite/node/stats'); const stats = require('ep_etherpad-lite/node/stats');
var sessionModule = require('express-session'); const sessionModule = require('express-session');
var cookieParser = require('cookie-parser'); const cookieParser = require('cookie-parser');
//checks for basic http auth exports.checkAccess = (req, res, next) => {
exports.basicAuth = function (req, res, next) { const hookResultMangle = (cb) => {
var hookResultMangle = function (cb) { return (err, data) => {
return function (err, data) {
return cb(!err && data.length && data[0]); return cb(!err && data.length && data[0]);
} };
} };
var authorize = function (cb) { // This may be called twice per access: once before authentication is checked and once after (if
// settings.requireAuthorization is true).
const authorize = (cb) => {
// Do not require auth for static paths and the API...this could be a bit brittle // Do not require auth for static paths and the API...this could be a bit brittle
if (req.path.match(/^\/(static|javascripts|pluginfw|api)/)) return cb(true); if (req.path.match(/^\/(static|javascripts|pluginfw|api)/)) return cb(true);
if (req.path.toLowerCase().indexOf('/admin') != 0) { if (req.path.toLowerCase().indexOf('/admin') !== 0) {
if (!settings.requireAuthentication) return cb(true); if (!settings.requireAuthentication) return cb(true);
if (!settings.requireAuthorization && req.session && req.session.user) return cb(true); if (!settings.requireAuthorization && req.session && req.session.user) return cb(true);
} }
if (req.session && req.session.user && req.session.user.is_admin) return cb(true); if (req.session && req.session.user && req.session.user.is_admin) return cb(true);
hooks.aCallFirst("authorize", {req: req, res:res, next:next, resource: req.path}, hookResultMangle(cb)); hooks.aCallFirst('authorize', {req, res, next, resource: req.path}, hookResultMangle(cb));
} };
var authenticate = function (cb) {
// If auth headers are present use them to authenticate...
if (req.headers.authorization && req.headers.authorization.search('Basic ') === 0) {
var userpass = Buffer.from(req.headers.authorization.split(' ')[1], 'base64').toString().split(":")
var username = userpass.shift();
var password = userpass.join(':');
var fallback = function(success) {
if (success) return cb(true);
if (settings.users[username] != undefined && settings.users[username].password === password) {
settings.users[username].username = username;
req.session.user = settings.users[username];
return cb(true);
}
return cb(false);
};
return hooks.aCallFirst("authenticate", {req: req, res:res, next:next, username: username, password: password}, hookResultMangle(fallback));
}
hooks.aCallFirst("authenticate", {req: req, res:res, next:next}, hookResultMangle(cb));
}
/* Authentication OR authorization failed. */ /* Authentication OR authorization failed. */
var failure = function () { const failure = () => {
return hooks.aCallFirst("authFailure", {req: req, res:res, next:next}, hookResultMangle(function (ok) { return hooks.aCallFirst('authFailure', {req, res, next}, hookResultMangle((ok) => {
if (ok) return; if (ok) return;
/* No plugin handler for invalid auth. Return Auth required // No plugin handled the authn/authz failure. Fall back to basic authentication.
* Headers, delayed for 1 second, if authentication failed
* before. */
res.header('WWW-Authenticate', 'Basic realm="Protected Area"'); res.header('WWW-Authenticate', 'Basic realm="Protected Area"');
if (req.headers.authorization) { // Delay the error response for 1s to slow down brute force attacks.
setTimeout(function () { setTimeout(() => {
res.status(401).send('Authentication required'); res.status(401).send('Authentication Required');
}, 1000); }, 1000);
} else {
res.status(401).send('Authentication required');
}
})); }));
} };
// Access checking is done in three steps:
//
// 1) Try to just access the thing. If access fails (perhaps authentication has not yet completed,
// or maybe different credentials are required), go to the next step.
// 2) Try to authenticate. (Or, if already logged in, reauthenticate with different credentials if
// supported by the authn scheme.) If authentication fails, give the user a 401 error to
// request new credentials. Otherwise, go to the next step.
// 3) Try to access the thing again. If this fails, give the user a 401 error.
//
// Plugins can use the 'next' callback (from the hook's context) to break out at any point (e.g.,
// to process an OAuth callback). Plugins can use the authFailure hook to override the default
// error handling behavior (e.g., to redirect to a login page).
/* This is the actual authentication/authorization hoop. It is done in four steps: let step1PreAuthenticate, step2Authenticate, step3Authorize;
1) Try to just access the thing step1PreAuthenticate = () => {
2) If not allowed using whatever creds are in the current session already, try to authenticate authorize((ok) => {
3) If authentication using already supplied credentials succeeds, try to access the thing again if (ok) return next();
4) If all els fails, give the user a 401 to request new credentials step2Authenticate();
Note that the process could stop already in step 3 with a redirect to login page.
*/
authorize(function (ok) {
if (ok) return next();
authenticate(function (ok) {
if (!ok) return failure();
authorize(function (ok) {
if (ok) return next();
failure();
});
}); });
}); };
}
step2Authenticate = () => {
const ctx = {req, res, next};
// If the HTTP basic auth header is present, extract the username and password so it can be
// given to authn plugins.
const httpBasicAuth =
req.headers.authorization && req.headers.authorization.search('Basic ') === 0;
if (httpBasicAuth) {
const userpass =
Buffer.from(req.headers.authorization.split(' ')[1], 'base64').toString().split(':');
ctx.username = userpass.shift();
ctx.password = userpass.join(':');
}
hooks.aCallFirst('authenticate', ctx, hookResultMangle((ok) => {
if (!ok) {
// Fall back to HTTP basic auth.
if (!httpBasicAuth) return failure();
if (!(ctx.username in settings.users)) {
httpLogger.info(`Failed authentication from IP ${req.ip} - no such user`);
return failure();
}
if (settings.users[ctx.username].password !== ctx.password) {
httpLogger.info(`Failed authentication from IP ${req.ip} for user ${ctx.username} - incorrect password`);
return failure();
}
httpLogger.info(`Successful authentication from IP ${req.ip} for user ${ctx.username}`);
settings.users[ctx.username].username = ctx.username;
req.session.user = settings.users[ctx.username];
}
step3Authorize();
}));
};
step3Authorize = () => {
authorize((ok) => {
if (ok) return next();
failure();
});
};
step1PreAuthenticate();
};
exports.secret = null; exports.secret = null;
exports.expressConfigure = function (hook_name, args, cb) { exports.expressConfigure = (hook_name, args, cb) => {
// Measure response time // Measure response time
args.app.use(function(req, res, next) { args.app.use((req, res, next) => {
var stopWatch = stats.timer('httpRequests').start(); const stopWatch = stats.timer('httpRequests').start();
var sendFn = res.send const sendFn = res.send;
res.send = function() { res.send = function() { // function, not arrow, due to use of 'arguments'
stopWatch.end() stopWatch.end();
sendFn.apply(res, arguments) sendFn.apply(res, arguments);
} };
next() next();
}) });
// If the log level specified in the config file is WARN or ERROR the application server never starts listening to requests as reported in issue #158. // If the log level specified in the config file is WARN or ERROR the application server never starts listening to requests as reported in issue #158.
// Not installing the log4js connect logger when the log level has a higher severity than INFO since it would not log at that level anyway. // Not installing the log4js connect logger when the log level has a higher severity than INFO since it would not log at that level anyway.
if (!(settings.loglevel === "WARN" || settings.loglevel == "ERROR")) if (!(settings.loglevel === 'WARN' || settings.loglevel === 'ERROR'))
args.app.use(log4js.connectLogger(httpLogger, { level: log4js.levels.DEBUG, format: ':status, :method :url'})); args.app.use(log4js.connectLogger(httpLogger, {level: log4js.levels.DEBUG, format: ':status, :method :url'}));
/* Do not let express create the session, so that we can retain a /* Do not let express create the session, so that we can retain a
* reference to it for socket.io to use. Also, set the key (cookie * reference to it for socket.io to use. Also, set the key (cookie
@ -122,6 +137,8 @@ exports.expressConfigure = function (hook_name, args, cb) {
exports.secret = settings.sessionKey; exports.secret = settings.sessionKey;
} }
const sameSite = settings.ssl ? 'Strict' : 'Lax';
args.app.sessionStore = exports.sessionStore; args.app.sessionStore = exports.sessionStore;
args.app.use(sessionModule({ args.app.use(sessionModule({
secret: exports.secret, secret: exports.secret,
@ -131,6 +148,12 @@ exports.expressConfigure = function (hook_name, args, cb) {
name: 'express_sid', name: 'express_sid',
proxy: true, proxy: true,
cookie: { cookie: {
/*
* Firefox started enforcing sameSite, see https://github.com/ether/etherpad-lite/issues/3989
* for details. In response we set it based on if SSL certs are set in Etherpad. Note that if
* You use Nginx or so for reverse proxy this may cause problems. Use Certificate pinning to remedy.
*/
sameSite: sameSite,
/* /*
* The automatic express-session mechanism for determining if the * The automatic express-session mechanism for determining if the
* application is being served over ssl is similar to the one used for * application is being served over ssl is similar to the one used for
@ -157,5 +180,5 @@ exports.expressConfigure = function (hook_name, args, cb) {
args.app.use(cookieParser(settings.sessionKey, {})); args.app.use(cookieParser(settings.sessionKey, {}));
args.app.use(exports.basicAuth); args.app.use(exports.checkAccess);
} };

View file

@ -3,9 +3,10 @@ var languages = require('languages4translatewiki')
, path = require('path') , path = require('path')
, _ = require('underscore') , _ = require('underscore')
, npm = require('npm') , npm = require('npm')
, plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins.js').plugins , plugins = require('ep_etherpad-lite/static/js/pluginfw/plugin_defs.js').plugins
, semver = require('semver') , semver = require('semver')
, existsSync = require('../utils/path_exists') , existsSync = require('../utils/path_exists')
, settings = require('../utils/Settings')
; ;
@ -43,7 +44,7 @@ function getAllLocales() {
//add plugins languages (if any) //add plugins languages (if any)
for(var pluginName in plugins) extractLangs(path.join(npm.root, pluginName, 'locales')); for(var pluginName in plugins) extractLangs(path.join(npm.root, pluginName, 'locales'));
// Build a locale index (merge all locale data) // Build a locale index (merge all locale data other than user-supplied overrides)
var locales = {} var locales = {}
_.each (locales2paths, function(files, langcode) { _.each (locales2paths, function(files, langcode) {
locales[langcode]={}; locales[langcode]={};
@ -54,6 +55,22 @@ function getAllLocales() {
}); });
}); });
// Add custom strings from settings.json
// Since this is user-supplied, we'll do some extra sanity checks
const wrongFormatErr = Error(
"customLocaleStrings in wrong format. See documentation " +
"for Customization for Administrators, under Localization.")
if (settings.customLocaleStrings) {
if (typeof settings.customLocaleStrings !== "object") throw wrongFormatErr
_.each(settings.customLocaleStrings, function(overrides, langcode) {
if (typeof overrides !== "object") throw wrongFormatErr
_.each(overrides, function(localeString, key) {
if (typeof localeString !== "string") throw wrongFormatErr
locales[langcode][key] = localeString
})
})
}
return locales; return locales;
} }

View file

@ -21,8 +21,9 @@
* limitations under the License. * limitations under the License.
*/ */
var log4js = require('log4js') const log4js = require('log4js')
, NodeVersion = require('./utils/NodeVersion') , NodeVersion = require('./utils/NodeVersion')
, UpdateCheck = require('./utils/UpdateCheck')
; ;
log4js.replaceConsole(); log4js.replaceConsole();
@ -38,6 +39,9 @@ NodeVersion.enforceMinNodeVersion('10.13.0');
*/ */
NodeVersion.checkDeprecationStatus('10.13.0', '1.8.3'); NodeVersion.checkDeprecationStatus('10.13.0', '1.8.3');
// Check if Etherpad version is up-to-date
UpdateCheck.check();
/* /*
* start up stats counting system * start up stats counting system
*/ */
@ -57,7 +61,6 @@ npm.load({}, function() {
var db = require('./db/DB'); var db = require('./db/DB');
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins"); var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins");
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks"); var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
hooks.plugins = plugins;
db.init() db.init()
.then(plugins.update) .then(plugins.update)

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