Merge branch 'soon' into staging

This commit is contained in:
ansuz 2020-03-27 19:59:45 -04:00
commit db9eaa8d4f
14 changed files with 904 additions and 544 deletions

View File

@ -17,10 +17,11 @@ module.exports.create = function (config) {
.on('sessionClose', historyKeeper.sessionClose)
.on('error', function (error, label, info) {
if (!error) { return; }
if (['EPIPE', 'ECONNRESET'].indexOf(error && error.code) !== -1) { return; }
/* labels:
SEND_MESSAGE_FAIL, SEND_MESSAGE_FAIL_2, FAIL_TO_DISCONNECT,
FAIL_TO_TERMINATE, HANDLE_CHANNEL_LEAVE, NETFLUX_BAD_MESSAGE,
NETFLUX_WEBSOCKET_ERROR
NETFLUX_WEBSOCKET_ERROR, NF_ENOENT
*/
log.error(label, {
code: error.code,

View File

@ -19,6 +19,26 @@ var getFileDescriptorLimit = function (env, server, cb) {
Ulimit(cb);
};
var getCacheStats = function (env, server, cb) {
var metaCount = 0;
var channelCount = 0;
var meta = env.metadata_cache;
for (var x in meta) {
if (meta.hasOwnProperty(x)) { metaCount++; }
}
var channels = env.channel_cache;
for (var y in channels) {
if (channels.hasOwnProperty(y)) { channelCount++; }
}
cb(void 0, {
metadata: metaCount,
channel: channelCount,
});
};
var getActiveSessions = function (Env, Server, cb) {
var stats = Server.getSessionStats();
cb(void 0, [
@ -137,6 +157,7 @@ var commands = {
GET_FILE_DESCRIPTOR_COUNT: getFileDescriptorCount,
GET_FILE_DESCRIPTOR_LIMIT: getFileDescriptorLimit,
SET_DEFAULT_STORAGE_LIMIT: setDefaultStorageLimit,
GET_CACHE_STATS: getCacheStats,
};
Admin.command = function (Env, safeKey, data, _cb, Server) {

View File

@ -61,43 +61,7 @@ Channel.removeOwnedChannel = function (Env, safeKey, channelId, cb, Server) {
var unsafeKey = Util.unescapeKeyCharacters(safeKey);
if (Env.blobStore.isFileId(channelId)) {
var blobId = channelId;
return void nThen(function (w) {
// check if you have permissions
Env.blobStore.isOwnedBy(safeKey, blobId, w(function (err, owned) {
if (err || !owned) {
w.abort();
return void cb("INSUFFICIENT_PERMISSIONS");
}
}));
}).nThen(function (w) {
// remove the blob
return void Env.blobStore.archive.blob(blobId, w(function (err) {
Env.Log.info('ARCHIVAL_OWNED_FILE_BY_OWNER_RPC', {
safeKey: safeKey,
blobId: blobId,
status: err? String(err): 'SUCCESS',
});
if (err) {
w.abort();
return void cb(err);
}
}));
}).nThen(function () {
// archive the proof
return void Env.blobStore.archive.proof(safeKey, blobId, function (err) {
Env.Log.info("ARCHIVAL_PROOF_REMOVAL_BY_OWNER_RPC", {
safeKey: safeKey,
blobId: blobId,
status: err? String(err): 'SUCCESS',
});
if (err) {
return void cb("E_PROOF_REMOVAL");
}
cb(void 0, 'OK');
});
});
return void Env.removeOwnedBlob(channelId, safeKey, cb);
}
Metadata.getMetadata(Env, channelId, function (err, metadata) {

View File

@ -2,7 +2,6 @@
const Core = require("./core");
const Pinning = module.exports;
const Nacl = require("tweetnacl/nacl-fast");
const Util = require("../common-util");
const nThen = require("nthen");

View File

@ -10,6 +10,7 @@ const Core = require("./commands/core");
const Store = require("./storage/file");
const BlobStore = require("./storage/blob");
const Workers = require("./workers/index");
module.exports.create = function (config, cb) {
const Log = config.log;
@ -78,8 +79,6 @@ module.exports.create = function (config, cb) {
domain: config.domain
};
HK.initializeValidationWorkers(Env);
(function () {
var pes = config.premiumUploadSize;
if (!isNaN(pes) && pes >= Env.maxUploadSize) {
@ -190,7 +189,7 @@ module.exports.create = function (config, cb) {
},
sessionClose: function (userId, reason) {
HK.closeNetfluxSession(Env, userId);
if (['BAD_MESSAGE', 'SOCKET_ERROR', 'SEND_MESSAGE_FAIL_2'].indexOf(reason) !== -1) {
if (['BAD_MESSAGE', 'SEND_MESSAGE_FAIL_2'].indexOf(reason) !== -1) {
if (reason && reason.code === 'ECONNRESET') { return; }
return void Log.error('SESSION_CLOSE_WITH_ERROR', {
userId: userId,
@ -243,9 +242,10 @@ module.exports.create = function (config, cb) {
Env.blobStore = blob;
}));
}).nThen(function (w) {
HK.initializeIndexWorkers(Env, {
Workers.initialize(Env, {
blobPath: config.blobPath,
blobStagingPath: config.blobStagingPath,
taskPath: config.taskPath,
pinPath: pinPath,
filePath: config.filePath,
archivePath: config.archivePath,
@ -258,25 +258,25 @@ module.exports.create = function (config, cb) {
}
}));
}).nThen(function (w) {
// create a task store
// create a task store (for scheduling tasks)
require("./storage/tasks").create(config, w(function (e, tasks) {
if (e) {
throw e;
}
if (e) { throw e; }
Env.tasks = tasks;
config.tasks = tasks;
if (config.disableIntegratedTasks) { return; }
config.intervals = config.intervals || {};
config.intervals.taskExpiration = setInterval(function () {
tasks.runAll(function (err) {
if (err) {
// either TASK_CONCURRENCY or an error with tasks.list
// in either case it is already logged.
}
});
}, 1000 * 60 * 5); // run every five minutes
}));
if (config.disableIntegratedTasks) { return; }
config.intervals = config.intervals || {};
var tasks_running;
config.intervals.taskExpiration = setInterval(function () {
if (tasks_running) { return; }
tasks_running = true;
Env.runTasks(function (err) {
if (err) {
Log.error('TASK_RUNNER_ERR', err);
}
tasks_running = false;
});
}, 1000 * 60 * 5); // run every five minutes
}).nThen(function () {
RPC.create(Env, function (err, _rpc) {
if (err) { throw err; }

View File

@ -6,10 +6,6 @@ const nThen = require('nthen');
const Util = require("./common-util");
const MetaRPC = require("./commands/metadata");
const Nacl = require('tweetnacl/nacl-fast');
const { fork } = require('child_process');
const OS = require("os");
const numCPUs = OS.cpus().length;
const now = function () { return (new Date()).getTime(); };
const ONE_DAY = 1000 * 60 * 60 * 24; // one day in milliseconds
@ -43,11 +39,14 @@ const STANDARD_CHANNEL_LENGTH = HK.STANDARD_CHANNEL_LENGTH = 32;
// with a 34 character id
const EPHEMERAL_CHANNEL_LENGTH = HK.EPHEMERAL_CHANNEL_LENGTH = 34;
const tryParse = function (Env, str) {
const tryParse = HK.tryParse = function (Env, str) {
try {
return JSON.parse(str);
} catch (err) {
Env.Log.error('HK_PARSE_ERROR', err);
Env.Log.error('HK_PARSE_ERROR', {
message: err && err.name,
input: str,
});
}
};
@ -767,249 +766,6 @@ HK.onDirectMessage = function (Env, Server, seq, userId, json) {
});
};
HK.initializeIndexWorkers = function (Env, config, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
const workers = [];
const response = Util.response();
const initWorker = function (worker, cb) {
//console.log("initializing index worker");
const txid = Util.uid();
response.expect(txid, function (err) {
if (err) { return void cb(err); }
//console.log("worker initialized");
workers.push(worker);
cb();
}, 15000);
worker.send({
txid: txid,
config: config,
});
worker.on('message', function (res) {
if (!res) { return; }
if (!res.txid) {
// !report errors...
if (res.error) {
Env.Log.error(res.error, res.value);
}
return;
}
//console.log(res);
try {
response.handle(res.txid, [res.error, res.value]);
} catch (err) {
Env.Log.error("INDEX_WORKER", {
error: err,
response: res,
});
}
});
worker.on('exit', function () {
var idx = workers.indexOf(worker);
if (idx !== -1) {
workers.splice(idx, 1);
}
var w = fork('lib/workers/compute-index');
initWorker(w, function (err) {
if (err) {
throw new Error(err);
}
workers.push(w);
});
});
};
var workerIndex = 0;
var sendCommand = function (msg, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
workerIndex = (workerIndex + 1) % workers.length;
if (workers.length === 0 ||
typeof(workers[workerIndex].send) !== 'function') {
return void cb("NO_WORKERS");
}
const txid = Util.uid();
msg.txid = txid;
response.expect(txid, cb, 45000);
workers[workerIndex].send(msg);
};
nThen(function (w) {
OS.cpus().forEach(function () {
initWorker(fork('lib/workers/compute-index'), w(function (err) {
if (!err) { return; }
w.abort();
return void cb(err);
}));
});
}).nThen(function () {
Env.computeIndex = function (Env, channel, cb) {
Env.store.getWeakLock(channel, function (next) {
sendCommand({
channel: channel,
command: 'COMPUTE_INDEX',
}, function (err, index) {
next();
cb(err, index);
});
});
};
Env.computeMetadata = function (channel, cb) {
Env.store.getWeakLock(channel, function (next) {
sendCommand({
channel: channel,
command: 'COMPUTE_METADATA',
}, function (err, metadata) {
next();
cb(err, metadata);
});
});
};
Env.getOlderHistory = function (channel, oldestKnownHash, cb) {
Env.store.getWeakLock(channel, function (next) {
sendCommand({
channel: channel,
command: "GET_OLDER_HISTORY",
hash: oldestKnownHash,
}, Util.both(next, cb));
});
};
Env.getPinState = function (safeKey, cb) {
Env.pinStore.getWeakLock(safeKey, function (next) {
sendCommand({
key: safeKey,
command: 'GET_PIN_STATE',
}, Util.both(next, cb));
});
};
Env.getFileSize = function (channel, cb) {
sendCommand({
command: 'GET_FILE_SIZE',
channel: channel,
}, cb);
};
Env.getDeletedPads = function (channels, cb) {
sendCommand({
command: "GET_DELETED_PADS",
channels: channels,
}, cb);
};
Env.getTotalSize = function (channels, cb) {
// we could take out locks for all of these channels,
// but it's OK if the size is slightly off
sendCommand({
command: 'GET_TOTAL_SIZE',
channels: channels,
}, cb);
};
Env.getMultipleFileSize = function (channels, cb) {
sendCommand({
command: "GET_MULTIPLE_FILE_SIZE",
channels: channels,
}, cb);
};
Env.getHashOffset = function (channel, hash, cb) {
Env.store.getWeakLock(channel, function (next) {
sendCommand({
command: 'GET_HASH_OFFSET',
channel: channel,
hash: hash,
}, Util.both(next, cb));
});
};
//console.log("index workers ready");
cb(void 0);
});
};
HK.initializeValidationWorkers = function (Env) {
if (typeof(Env.validateMessage) !== 'undefined') {
return void console.error("validation workers are already initialized");
}
// Create our workers
const workers = [];
for (let i = 0; i < numCPUs; i++) {
workers.push(fork('lib/workers/check-signature.js'));
}
const response = Util.response();
var initWorker = function (worker) {
worker.on('message', function (res) {
if (!res || !res.txid) { return; }
//console.log(+new Date(), "Received verification response");
response.handle(res.txid, [res.error, res.value]);
});
// Spawn a new process in one ends
worker.on('exit', function () {
var idx = workers.indexOf(worker);
if (idx !== -1) {
workers.splice(idx, 1);
}
// Spawn a new one
var w = fork('lib/workers/check-signature.js');
workers.push(w);
initWorker(w);
});
};
workers.forEach(initWorker);
var nextWorker = 0;
const send = function (msg, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
// let's be paranoid about asynchrony and only calling back once..
nextWorker = (nextWorker + 1) % workers.length;
if (workers.length === 0 || typeof(workers[nextWorker].send) !== 'function') {
return void cb("INVALID_WORKERS");
}
var txid = msg.txid = Util.uid();
// expect a response within 15s
response.expect(txid, cb, 15000);
// Send the request
workers[nextWorker].send(msg);
};
Env.validateMessage = function (signedMsg, key, cb) {
send({
msg: signedMsg,
key: key,
command: 'INLINE',
}, cb);
};
Env.checkSignature = function (signedMsg, signature, publicKey, cb) {
send({
command: 'DETACHED',
sig: signature,
msg: signedMsg,
key: publicKey,
}, cb);
};
Env.hashChannelList = function (channels, cb) {
send({
command: 'HASH_CHANNEL_LIST',
channels: channels,
}, cb);
};
};
/* onChannelMessage
Determine what we should store when a message a broadcasted to a channel"

View File

@ -21,7 +21,7 @@ var write = function (ctx, content) {
};
// various degrees of logging
const logLevels = ['silly', 'verbose', 'debug', 'feedback', 'info', 'warn', 'error'];
const logLevels = Logger.levels = ['silly', 'verbose', 'debug', 'feedback', 'info', 'warn', 'error'];
var handlers = {
silly: function (ctx, time, tag, info) {

View File

@ -10,8 +10,23 @@ const Meta = require("../metadata");
const Pins = require("../pins");
const Core = require("../commands/core");
const Saferphore = require("saferphore");
const Logger = require("../log");
const Tasks = require("../storage/tasks");
const Env = {};
const Env = {
Log: {},
};
// support the usual log API but pass it to the main process
Logger.levels.forEach(function (level) {
Env.Log[level] = function (label, info) {
process.send({
log: level,
label: label,
info: info,
});
};
});
var ready = false;
var store;
@ -52,15 +67,23 @@ const init = function (config, _cb) {
}
blobStore = blob;
}));
}).nThen(function (w) {
Tasks.create({
log: Env.Log,
taskPath: config.taskPath,
store: store,
}, w(function (err, tasks) {
if (err) {
w.abort();
return void cb(err);
}
Env.tasks = tasks;
}));
}).nThen(function () {
cb();
});
};
const tryParse = function (Env, str) {
try { return JSON.parse(str); } catch (err) { }
};
/* computeIndex
can call back with an error or a computed index which includes:
* cpIndex:
@ -107,7 +130,7 @@ const computeIndex = function (data, cb) {
// but only check for metadata on the first line
if (!i && msgObj.buff.indexOf('{') === 0) {
i++; // always increment the message counter
msg = tryParse(Env, msgObj.buff.toString('utf8'));
msg = HK.tryParse(Env, msgObj.buff.toString('utf8'));
if (typeof msg === "undefined") { return readMore(); }
// validate that the current line really is metadata before storing it as such
@ -116,7 +139,7 @@ const computeIndex = function (data, cb) {
}
i++;
if (msgObj.buff.indexOf('cp|') > -1) {
msg = msg || tryParse(Env, msgObj.buff.toString('utf8'));
msg = msg || HK.tryParse(Env, msgObj.buff.toString('utf8'));
if (typeof msg === "undefined") { return readMore(); }
// cache the offsets of checkpoints if they can be parsed
if (msg[2] === 'MSG' && msg[4].indexOf('cp|') === 0) {
@ -142,7 +165,7 @@ const computeIndex = function (data, cb) {
// once indexing is complete you should have a buffer of messages since the latest checkpoint
// map the 'hash' of each message to its byte offset in the log, to be used for reconnecting clients
messageBuf.forEach((msgObj) => {
const msg = tryParse(Env, msgObj.buff.toString('utf8'));
const msg = HK.tryParse(Env, msgObj.buff.toString('utf8'));
if (typeof msg === "undefined") { return; }
if (msg[0] === 0 && msg[2] === 'MSG' && typeof(msg[4]) === 'string') {
// msgObj.offset is API guaranteed by our storage module
@ -166,9 +189,9 @@ const computeIndex = function (data, cb) {
});
};
const computeMetadata = function (data, cb, errorHandler) {
const computeMetadata = function (data, cb) {
const ref = {};
const lineHandler = Meta.createLineHandler(ref, errorHandler);
const lineHandler = Meta.createLineHandler(ref, Env.Log.error);
return void store.readChannelMetadata(data.channel, lineHandler, function (err) {
if (err) {
// stream errors?
@ -199,7 +222,7 @@ const getOlderHistory = function (data, cb) {
store.getMessages(channelName, function (msgStr) {
if (found) { return; }
let parsed = tryParse(Env, msgStr);
let parsed = HK.tryParse(Env, msgStr);
if (typeof parsed === "undefined") { return; }
// identify classic metadata messages by their inclusion of a channel.
@ -221,11 +244,11 @@ const getOlderHistory = function (data, cb) {
});
};
const getPinState = function (data, cb, errorHandler) {
const getPinState = function (data, cb) {
const safeKey = data.key;
var ref = {};
var lineHandler = Pins.createLineHandler(ref, errorHandler);
var lineHandler = Pins.createLineHandler(ref, Env.Log.error);
// if channels aren't in memory. load them from disk
// TODO replace with readMessagesBin
@ -328,7 +351,7 @@ const getHashOffset = function (data, cb) {
var offset = -1;
store.readMessagesBin(channelName, 0, (msgObj, readMore, abort) => {
// tryParse return a parsed message or undefined
const msg = tryParse(Env, msgObj.buff.toString('utf8'));
const msg = HK.tryParse(Env, msgObj.buff.toString('utf8'));
// if it was undefined then go onto the next message
if (typeof msg === "undefined") { return readMore(); }
if (typeof(msg[4]) !== 'string' || lastKnownHash !== HK.getHash(msg[4])) {
@ -342,6 +365,51 @@ const getHashOffset = function (data, cb) {
});
};
const removeOwnedBlob = function (data, cb) {
const blobId = data.blobId;
const safeKey = data.safeKey;
nThen(function (w) {
// check if you have permissions
blobStore.isOwnedBy(safeKey, blobId, w(function (err, owned) {
if (err || !owned) {
w.abort();
return void cb("INSUFFICIENT_PERMISSIONS");
}
}));
}).nThen(function (w) {
// remove the blob
blobStore.archive.blob(blobId, w(function (err) {
Env.Log.info('ARCHIVAL_OWNED_FILE_BY_OWNER_RPC', {
safeKey: safeKey,
blobId: blobId,
status: err? String(err): 'SUCCESS',
});
if (err) {
w.abort();
return void cb(err);
}
}));
}).nThen(function () {
// archive the proof
blobStore.archive.proof(safeKey, blobId, function (err) {
Env.Log.info("ARCHIVAL_PROOF_REMOVAL_BY_OWNER_RPC", {
safeKey: safeKey,
blobId: blobId,
status: err? String(err): 'SUCCESS',
});
if (err) {
return void cb("E_PROOF_REMOVAL");
}
cb(void 0, 'OK');
});
});
};
const runTasks = function (data, cb) {
Env.tasks.runAll(cb);
};
const COMMANDS = {
COMPUTE_INDEX: computeIndex,
COMPUTE_METADATA: computeMetadata,
@ -352,12 +420,15 @@ const COMMANDS = {
GET_DELETED_PADS: getDeletedPads,
GET_MULTIPLE_FILE_SIZE: getMultipleFileSize,
GET_HASH_OFFSET: getHashOffset,
REMOVE_OWNED_BLOB: removeOwnedBlob,
RUN_TASKS: runTasks,
};
process.on('message', function (data) {
if (!data || !data.txid) {
if (!data || !data.txid || !data.pid) {
return void process.send({
error:'E_INVAL'
error:'E_INVAL',
data: data,
});
}
@ -365,6 +436,7 @@ process.on('message', function (data) {
process.send({
error: err,
txid: data.txid,
pid: data.pid,
value: value,
});
};
@ -381,12 +453,12 @@ process.on('message', function (data) {
if (typeof(command) !== 'function') {
return void cb("E_BAD_COMMAND");
}
command(data, cb, function (label, info) {
// for streaming errors
process.send({
error: label,
value: info,
});
});
command(data, cb);
});
process.on('uncaughtException', function (err) {
console.error('[%s] UNCAUGHT EXCEPTION IN DB WORKER', new Date());
console.error(err);
console.error("TERMINATING");
process.exit(1);
});

339
lib/workers/index.js Normal file
View File

@ -0,0 +1,339 @@
/* jshint esversion: 6 */
/* global process */
const Util = require("../common-util");
const nThen = require('nthen');
const OS = require("os");
const numCPUs = OS.cpus().length;
const { fork } = require('child_process');
const Workers = module.exports;
const PID = process.pid;
const CRYPTO_PATH = 'lib/workers/crypto-worker';
const DB_PATH = 'lib/workers/db-worker';
Workers.initializeValidationWorkers = function (Env) {
if (typeof(Env.validateMessage) !== 'undefined') {
return void console.error("validation workers are already initialized");
}
// Create our workers
const workers = [];
for (let i = 0; i < numCPUs; i++) {
workers.push(fork(CRYPTO_PATH));
}
const response = Util.response(function (errLabel, info) {
Env.Log.error('HK_VALIDATE_WORKER__' + errLabel, info);
});
var initWorker = function (worker) {
worker.on('message', function (res) {
if (!res || !res.txid) { return; }
response.handle(res.txid, [res.error, res.value]);
});
var substituteWorker = Util.once( function () {
Env.Log.info("SUBSTITUTE_VALIDATION_WORKER", '');
var idx = workers.indexOf(worker);
if (idx !== -1) {
workers.splice(idx, 1);
}
// Spawn a new one
var w = fork(CRYPTO_PATH);
workers.push(w);
initWorker(w);
});
// Spawn a new process in one ends
worker.on('exit', substituteWorker);
worker.on('close', substituteWorker);
worker.on('error', function (err) {
substituteWorker();
Env.Log.error('VALIDATION_WORKER_ERROR', {
error: err,
});
});
};
workers.forEach(initWorker);
var nextWorker = 0;
const send = function (msg, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
// let's be paranoid about asynchrony and only calling back once..
nextWorker = (nextWorker + 1) % workers.length;
if (workers.length === 0 || typeof(workers[nextWorker].send) !== 'function') {
return void cb("INVALID_WORKERS");
}
var txid = msg.txid = Util.uid();
// expect a response within 45s
response.expect(txid, cb, 60000);
// Send the request
workers[nextWorker].send(msg);
};
Env.validateMessage = function (signedMsg, key, cb) {
send({
msg: signedMsg,
key: key,
command: 'INLINE',
}, cb);
};
Env.checkSignature = function (signedMsg, signature, publicKey, cb) {
send({
command: 'DETACHED',
sig: signature,
msg: signedMsg,
key: publicKey,
}, cb);
};
Env.hashChannelList = function (channels, cb) {
send({
command: 'HASH_CHANNEL_LIST',
channels: channels,
}, cb);
};
};
Workers.initializeIndexWorkers = function (Env, config, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
const workers = [];
const response = Util.response(function (errLabel, info) {
Env.Log.error('HK_DB_WORKER__' + errLabel, info);
});
const Log = Env.Log;
const handleLog = function (level, label, info) {
if (typeof(Log[level]) !== 'function') { return; }
Log[level](label, info);
};
var isWorker = function (value) {
return value && value.worker && typeof(value.worker.send) === 'function';
};
// pick ids that aren't already in use...
const guid = function () {
var id = Util.uid();
return response.expected(id)? guid(): id;
};
var workerIndex = 0;
var sendCommand = function (msg, _cb) {
var cb = Util.once(Util.mkAsync(_cb));
workerIndex = (workerIndex + 1) % workers.length;
if (!isWorker(workers[workerIndex])) {
return void cb("NO_WORKERS");
}
var state = workers[workerIndex];
// XXX insert a queue here to prevent timeouts
const txid = guid();
msg.txid = txid;
msg.pid = PID;
// track which worker is doing which jobs
state.tasks[txid] = msg;
response.expect(txid, function (err, value) {
// clean up when you get a response
delete state[txid];
cb(err, value);
}, 60000);
state.worker.send(msg);
};
const initWorker = function (worker, cb) {
const txid = guid();
const state = {
worker: worker,
tasks: {},
};
response.expect(txid, function (err) {
if (err) { return void cb(err); }
workers.push(state);
cb(void 0, state);
}, 15000);
worker.send({
pid: PID,
txid: txid,
config: config,
});
worker.on('message', function (res) {
if (!res) { return; }
// handle log messages before checking if it was addressed to your PID
// it might still be useful to know what happened inside an orphaned worker
if (res.log) {
return void handleLog(res.log, res.label, res.info);
}
// but don't bother handling things addressed to other processes
// since it's basically guaranteed not to work
if (res.pid !== PID) {
return void Log.error("WRONG_PID", res);
}
response.handle(res.txid, [res.error, res.value]);
});
var substituteWorker = Util.once(function () {
Env.Log.info("SUBSTITUTE_DB_WORKER", '');
var idx = workers.indexOf(state);
if (idx !== -1) {
workers.splice(idx, 1);
}
Object.keys(state.tasks).forEach(function (txid) {
const cb = response.expectation(txid);
if (typeof(cb) !== 'function') { return; }
const task = state.tasks[txid];
if (!task && task.msg) { return; }
response.clear(txid);
Log.info('DB_WORKER_RESEND', task.msg);
sendCommand(task.msg, cb);
});
var w = fork(DB_PATH);
initWorker(w, function (err, state) {
if (err) {
throw new Error(err);
}
workers.push(state);
});
});
worker.on('exit', substituteWorker);
worker.on('close', substituteWorker);
worker.on('error', function (err) {
substituteWorker();
Env.Log.error("DB_WORKER_ERROR", {
error: err,
});
});
};
nThen(function (w) {
OS.cpus().forEach(function () {
initWorker(fork(DB_PATH), w(function (err) {
if (!err) { return; }
w.abort();
return void cb(err);
}));
});
}).nThen(function () {
Env.computeIndex = function (Env, channel, cb) {
Env.store.getWeakLock(channel, function (next) {
sendCommand({
channel: channel,
command: 'COMPUTE_INDEX',
}, function (err, index) {
next();
cb(err, index);
});
});
};
Env.computeMetadata = function (channel, cb) {
Env.store.getWeakLock(channel, function (next) {
sendCommand({
channel: channel,
command: 'COMPUTE_METADATA',
}, function (err, metadata) {
next();
cb(err, metadata);
});
});
};
Env.getOlderHistory = function (channel, oldestKnownHash, cb) {
Env.store.getWeakLock(channel, function (next) {
sendCommand({
channel: channel,
command: "GET_OLDER_HISTORY",
hash: oldestKnownHash,
}, Util.both(next, cb));
});
};
Env.getPinState = function (safeKey, cb) {
Env.pinStore.getWeakLock(safeKey, function (next) {
sendCommand({
key: safeKey,
command: 'GET_PIN_STATE',
}, Util.both(next, cb));
});
};
Env.getFileSize = function (channel, cb) {
sendCommand({
command: 'GET_FILE_SIZE',
channel: channel,
}, cb);
};
Env.getDeletedPads = function (channels, cb) {
sendCommand({
command: "GET_DELETED_PADS",
channels: channels,
}, cb);
};
Env.getTotalSize = function (channels, cb) {
// we could take out locks for all of these channels,
// but it's OK if the size is slightly off
sendCommand({
command: 'GET_TOTAL_SIZE',
channels: channels,
}, cb);
};
Env.getMultipleFileSize = function (channels, cb) {
sendCommand({
command: "GET_MULTIPLE_FILE_SIZE",
channels: channels,
}, cb);
};
Env.getHashOffset = function (channel, hash, cb) {
Env.store.getWeakLock(channel, function (next) {
sendCommand({
command: 'GET_HASH_OFFSET',
channel: channel,
hash: hash,
}, Util.both(next, cb));
});
};
Env.removeOwnedBlob = function (blobId, safeKey, cb) {
sendCommand({
command: 'REMOVE_OWNED_BLOB',
blobId: blobId,
safeKey: safeKey,
}, cb);
};
Env.runTasks = function (cb) {
sendCommand({
command: 'RUN_TASKS',
}, cb);
};
cb(void 0);
});
};
Workers.initialize = function (Env, config, cb) {
Workers.initializeValidationWorkers(Env);
Workers.initializeIndexWorkers(Env, config, cb);
};

View File

@ -81,10 +81,16 @@
});
};
Util.response = function () {
Util.response = function (errorHandler) {
var pending = {};
var timeouts = {};
if (typeof(errorHandler) !== 'function') {
errorHandler = function (label) {
throw new Error(label);
};
}
var clear = function (id) {
clearTimeout(timeouts[id]);
delete timeouts[id];
@ -92,8 +98,8 @@
};
var expect = function (id, fn, ms) {
if (typeof(id) !== 'string') { throw new Error("EXPECTED_STRING"); }
if (typeof(fn) !== 'function') { throw new Error("EXPECTED_CALLBACK"); }
if (typeof(id) !== 'string') { errorHandler('EXPECTED_STRING'); }
if (typeof(fn) !== 'function') { errorHandler('EXPECTED_CALLBACK'); }
pending[id] = fn;
if (typeof(ms) === 'number' && ms) {
timeouts[id] = setTimeout(function () {
@ -105,8 +111,21 @@
var handle = function (id, args) {
var fn = pending[id];
if (typeof(fn) !== 'function') { throw new Error("MISSING_CALLBACK"); }
pending[id].apply(null, Array.isArray(args)? args : [args]);
if (typeof(fn) !== 'function') {
errorHandler("MISSING_CALLBACK", {
id: id,
args: args,
});
}
try {
pending[id].apply(null, Array.isArray(args)? args : [args]);
} catch (err) {
errorHandler('HANDLER_ERROR', {
error: err,
id: id,
args: args,
});
}
clear(id);
};
@ -115,6 +134,9 @@
expected: function (id) {
return Boolean(pending[id]);
},
expectation: function (id) {
return pending[id];
},
expect: expect,
handle: handle,
};

View File

@ -864,7 +864,7 @@
"title": "Otras preguntas",
"pay": {
"q": "¿ Porque debería de pagar cuando hay características que son gratis ?",
"a": "Brindamos a los seguidores almacenamiento adicional y la capacidad de aumentar las cuotas de sus amigos (<a href='https://accounts.cryptpad.fr/#/faq' target='_blank'> obtener más información </a>). <Br > <br> Más allá de estos beneficios a corto plazo, al suscribirse con una cuenta premium, usted ayuda a financiar el desarrollo continuo y activo de CryptPad. Eso incluye corregir errores, agregar nuevas funciones y facilitar que otros ayuden a alojar CryptPad ellos mismos. Además, ayuda a demostrar a otros proveedores de servicios que las personas están dispuestas a apoyar las tecnologías que mejoran la privacidad. Esperamos que eventualmente los modelos de negocio basados en la venta de datos de usuarios se conviertan en cosa del pasado. <br> <br> Finalmente, ofrecemos la mayor parte de la funcionalidad de CryptPad de forma gratuita porque creemos que todos merecen privacidad personal, no solo aquellos con desechables. ingresos. Al apoyarnos, nos ayuda a continuar haciendo posible que las poblaciones desfavorecidas accedan a estas funciones básicas sin una etiqueta de precio adjunta."
"a": "Brindamos a los seguidores almacenamiento adicional y la capacidad de aumentar las cuotas de sus contactos (<a href='https://accounts.cryptpad.fr/#/faq' target='_blank'> obtener más información </a>). <Br > <br> Más allá de estos beneficios a corto plazo, al suscribirse con una cuenta premium, usted ayuda a financiar el desarrollo continuo y activo de CryptPad. Eso incluye corregir errores, agregar nuevas funciones y facilitar que otros ayuden a alojar CryptPad ellos mismos. Además, ayuda a demostrar a otros proveedores de servicios que las personas están dispuestas a apoyar las tecnologías que mejoran la privacidad. Esperamos que eventualmente los modelos de negocio basados en la venta de datos de usuarios se conviertan en cosa del pasado. <br> <br> Finalmente, ofrecemos la mayor parte de la funcionalidad de CryptPad de forma gratuita porque creemos que todos merecen privacidad personal, no solo aquellos con desechables. ingresos. Al apoyarnos, nos ayuda a continuar haciendo posible que las poblaciones desfavorecidas accedan a estas funciones básicas sin una etiqueta de precio adjunta."
},
"goal": {
"q": "¿Cuál es tu objetivo?",
@ -916,7 +916,7 @@
"settings": "Configura las diapositivas (fondo, transiciones, números de página, etc.) con el botón <span class=\"fa fa-cog\"></span> en el submenú <span class=\"fa fa-ellipsis-h\"></span>"
},
"poll": {
"decisions": "Crea decisiones en privado entre verdaderos amigos",
"decisions": "Crea decisiones en privado entre contactos de confianza",
"options": "Proponga opciones y exprese sus preferencias",
"choices": "Haga clic en las celdas de su columna para recorrer sí (<strong> ✔ </strong>), tal vez (<strong> ~ </strong>) o no (<strong> ✖ </strong>)",
"submit": "Haga clic en <strong> enviar </strong> para que otras personas puedan ver sus opciones"
@ -927,8 +927,8 @@
"embed": "Incrusta imágenes de tu disco <span class=\"fa fa-file-image-o\"></span> o de tu CryptDrive <span class=\"fa fa-image\"></span> y expórtalas como PNG a tu disco <span class=\"fa fa-download\"></span> o a tu CryptDrive <span class=\"fa fa-cloud-upload\"></span>"
},
"kanban": {
"add": "Añada nuevas placas usando el botón <span class=\"fa fa-plus\"></span> en la esquina superior derecha",
"task": "Mover objetos arrastrándolos y soltándolos de un tablero a otro",
"add": "Añada nuevas fichas y cuadros usando el botón <span class=\"fa fa-plus\"></span>",
"task": "Mover objetos arrastrándolos y soltándolos, arrastrándolo <span class=\"fa fa-trash\"></span> al basurero para borarlo",
"color": "Cambie los colores haciendo clic en la parte coloreada junto a los títulos de los tableros"
}
},

View File

@ -25,7 +25,7 @@
"common_connectionLost": "<b>Connessione al server persa</b><br>Rimarrai in modalità solo lettura finché la connessione non sarà ripristinata.",
"websocketError": "Impossibile connettersi al WebSocket server...",
"typeError": "Questo pad non è compatibile con l'applicazione selezionata",
"onLogout": "Sei uscito, {0}Clicca qui{1} per entrare<br>o premi <em>Esc</em> per accedere al tuo pad in modalità solo lettura.",
"onLogout": "Sei uscito, {0}clicca qui{1} per entrare<br>o premi <em>Esc</em> per accedere al tuo pad in modalità solo lettura.",
"wrongApp": "Impossibile mostrare il contenuto di quella sessione in tempo reale nel tuo browser. Per favore, prova a ricaricare quella pagina.",
"padNotPinned": "Questo pad scadrà dopo 3 mesi di inattività, {0}accedi{1} o {2}registrati{3} per conservarlo.",
"anonymousStoreDisabled": "Il webmaster di questa istanza di CryptPad ha disabilitato il drive per gli utenti anonimi. Devi accedere per poter usare CryptDrive.",
@ -36,25 +36,25 @@
"invalidHashError": "Il documento richiesto ha un URL non valido.",
"errorCopy": " Puoi ancora accedere al contenuto premendo <em>Esc</em>.<br>Una volta chiusa questa finestra, non sarà possibile accedere di nuovo.",
"errorRedirectToHome": "Premi <em>Esc</em> per essere reindirizzato al tuo CryptDrive.",
"newVersionError": "Una nuova versione di CryptPad è disponibile. <br><a href='#'>Ricarica</a> per usare la nuova versione, o premi Esc per accedere al contenuto in <b>modalità offline</b>.",
"loading": "Caricamento...",
"newVersionError": "Una nuova versione di CryptPad è disponibile. <br><a href='#'>Ricarica</a> per usare la nuova versione, o premi Esc per accedere al tuo contenuto in <b>modalità offline</b>.",
"loading": "Caricamento in corso...",
"error": "Errore",
"saved": "Salvato",
"synced": "È stato tutto salvato",
"deleted": "Cancellato",
"deletedFromServer": "Pad cancellato dal server",
"mustLogin": "Devi essere loggato per poter accedere a questa pagina",
"synced": "Tutto è stato salvato",
"deleted": "Eliminato",
"deletedFromServer": "Pad eliminato dal server",
"mustLogin": "Devi essere connesso per accedere a questa pagina",
"disabledApp": "Questa applicazione è stata disattivata. Contatta l'amministratore di questo CryptPad per ulteriori informazioni.",
"realtime_unrecoverableError": "Si è verificato un errore critico. Premi OK per ricaricare la pagina.",
"realtime_unrecoverableError": "Si è verificato un errore critico. Premi OK per ricaricare.",
"disconnected": "Disconnesso",
"synchronizing": "Sincronizzazione",
"reconnecting": "Riconnessione",
"synchronizing": "Sincronizzazione in corso",
"reconnecting": "Riconnessione in corso",
"typing": "Modifica",
"initializing": "Inizializzazione...",
"initializing": "Inizializzazione in corso...",
"forgotten": "Spostato nel cestino",
"errorState": "Errore critico: {0}",
"lag": "Latenza",
"readonly": "Solo lettura",
"readonly": "Sola lettura",
"anonymous": "Anonimo",
"yourself": "Da solo",
"anonymousUsers": "editori anonimi",
@ -65,10 +65,10 @@
"viewers": "visualizzatori",
"editor": "editore",
"editors": "editori",
"userlist_offline": "Sei offline, la lista degli utenti non è disponibile.",
"userlist_offline": "Sei offline, l'elenco degli utenti non è disponibile.",
"language": "Lingua",
"comingSoon": "In arrivo...",
"newVersion": "<b>CryptPad è stato aggiornato!</b><br>Scopri cosa c'è di nuovo nell'ultima versione:<br><a href=\"https://github.com/xwiki-labs/cryptpad/releases/tag/{0}\" target=\"_blank\">Note di rilascio per CryptPad {0}</a>",
"newVersion": "<b>CryptPad è stato aggiornato!</b><br>Scopri cosa c'è di nuovo nell'ultima versione:<br><a href=\"https://github.com/xwiki-labs/cryptpad/releases/tag/{0}\" target=\"_blank\">note di rilascio di CryptPad {0}</a>",
"upgrade": "Aumenta il limite",
"upgradeTitle": "Effettua l'upgrade del tuo account per incrementare il limite di spazio",
"upgradeAccount": "Upgrade dell'account",
@ -92,20 +92,20 @@
"importButtonTitle": "Importa un pad da un file locale",
"exportButton": "Esporta",
"exportButtonTitle": "Esporta questo pad in un file locale",
"exportPrompt": "Che nome vuoi dare al file?",
"exportPrompt": "Che nome vuoi dare al tuo file?",
"changeNamePrompt": "Cambia il tuo nome (lascia vuoto per essere anonimo): ",
"user_rename": "Cambia il nome mostrato",
"user_displayName": "Nome mostrato",
"user_accountName": "Nome dell'utente",
"user_accountName": "Nome dell'account",
"clickToEdit": "Clicca per modificare",
"saveTitle": "Salva il titolo (Enter)",
"forgetButton": "Cancella",
"forgetButtonTitle": "Muovi questo pad nel cestino",
"forgetPrompt": "Cliccando OK, questo pad sarà spostato nel cestino. Sei sicuro?",
"saveTitle": "Salva il titolo (Invio)",
"forgetButton": "Elimina",
"forgetButtonTitle": "Sposta questo pad nel cestino",
"forgetPrompt": "Cliccando OK questo pad sarà spostato nel cestino. Sei sicuro?",
"movedToTrash": "Questo pad è stato spostato nel cestino. <br><a href=\"/drive/\">Accedi al mio Drive</a>",
"shareButton": "Condividi",
"shareSuccess": "Copiato nella clipboard",
"userListButton": "Lista degli utenti",
"shareSuccess": "Link copiato negli appunti",
"userListButton": "Elenco degli utenti",
"chatButton": "Chat",
"userAccountButton": "Il tuo account",
"newButton": "Nuovo",
@ -117,7 +117,7 @@
"templateSaved": "Modello salvato!",
"selectTemplate": "Seleziona un modello o premi Esc",
"useTemplate": "Cominciare con un modello?",
"useTemplateOK": "Scegli un modello (Enter)",
"useTemplateOK": "Scegli un modello (Invio)",
"useTemplateCancel": "Documento vuoto (Esc)",
"template_import": "Importa un modello",
"template_empty": "Nessun modello disponibile",
@ -128,33 +128,33 @@
"propertiesButton": "Proprietà",
"propertiesButtonTitle": "Mostra proprietà del pad",
"printText": "Stampa",
"printButton": "Stampa (Enter)",
"printButtonTitle2": "Stampa il documento o esportalo come PDF",
"printButton": "Stampa (Invio)",
"printButtonTitle2": "Stampa il tuo documento o esportalo come file PDF",
"printOptions": "Opzioni di layout",
"printSlideNumber": "Mostra il numero della slide",
"printDate": "Mostra la data",
"printTitle": "Mostra il titolo del pad",
"printCSS": "Personalizza lo stile (CSS):",
"printTransition": "Attiva le animazioni di transizione",
"printBackground": "Usa una immagine di sfondo",
"printBackgroundButton": "Scegli una immagine",
"printBackgroundValue": "<b>Sfondo attuale</b> <em>{0}</em>",
"printBackgroundNoValue": "<em>Nessuno sfondo mostrato</em>",
"printBackground": "Usa un'immagine di sfondo",
"printBackgroundButton": "Scegli un'immagine",
"printBackgroundValue": "<b>Sfondo attuale:</b> <em>{0}</em>",
"printBackgroundNoValue": "<em>Nessuna immagine di sfondo mostrata</em>",
"printBackgroundRemove": "Rimuovi questa immagine di sfondo",
"filePickerButton": "Inserisci un file salvato in CryptDrive",
"filePickerButton": "Incorpora un file salvato in CryptDrive",
"filePicker_close": "Chiudi",
"filePicker_description": "Scegli un file dal tuo CryptDrive da inserire oppure caricane uno nuovo",
"filePicker_filter": "Filtra file per nome",
"filePicker_description": "Scegli un file dal tuo CryptDrive da incorporare o caricane uno nuovo",
"filePicker_filter": "Filtra i file per nome",
"or": "o",
"tags_title": "Tags (mostrati solo a te)",
"tags_add": "Aggiorna i tags di questa pagina",
"tags_title": "Tag (mostrati solo a te)",
"tags_add": "Aggiorna i tag di questa pagina",
"tags_searchHint": "Inizia una ricerca con # nel tuo CryptDrive per trovare i pad taggati.",
"tags_notShared": "I tuoi tags non sono condivisi con altri utenti",
"tags_notShared": "I tuoi tag non sono condivisi con altri utenti",
"tags_duplicate": "Duplica tag: {0}",
"tags_noentry": "Non puoi taggare un pad cancellato!",
"tags_noentry": "Non puoi taggare un pad eliminato!",
"slideOptionsText": "Opzioni",
"slideOptionsTitle": "Personalizza la presentazione",
"slideOptionsButton": "Salva (Enter)",
"slideOptionsButton": "Salva (Invio)",
"slide_invalidLess": "Stile personalizzato non valido",
"languageButton": "Lingua",
"languageButtonTitle": "Seleziona la lingua da utilizzare per l'evidenziazione della sintassi",
@ -164,37 +164,37 @@
"editShareTitle": "Copia il link per modifica nella clipboard",
"editOpen": "Apri il link per modifica in una nuova finestra",
"editOpenTitle": "Apri questo pad in modalità modifica in una nuova finestra",
"viewShare": "Link solo lettura",
"viewShareTitle": "Copia il link solo lettura nella clipboard",
"viewOpen": "Apri il link solo lettura in una nuova finestra",
"viewOpenTitle": "Apri questo pad in modalità solo lettura in una nuova finestra",
"viewShare": "Link per sola lettura",
"viewShareTitle": "Copia il link per sola lettura negli appunti",
"viewOpen": "Apri il link per sola lettura in una nuova scheda",
"viewOpenTitle": "Apri questo pad in modalità di sola lettura in una nuova scheda",
"fileShare": "Copia il link",
"getEmbedCode": "Mostra il codice per embedding",
"viewEmbedTag": "Per fare l'embed di questo pad, includi questo iframe nella tua pagina dovunque tu voglia. Puoi modificarne lo stile con gli attributi HTML o CSS.",
"fileEmbedTitle": "Fai l'embed di questo file in una pagina esterna",
"fileEmbedTitle": "Incorpora il file in una pagina esterna",
"fileEmbedScript": "Per fare l'embed di questo file, includi questo script una volta nella tua pagina per caricare il Media Tag:",
"fileEmbedTag": "Quindi posiziona il Media Tag dovunque tu voglia nella tua pagina:",
"notifyJoined": "{0} si è ricollegato alla sessione collaborativa",
"notifyJoined": "{0} si è unito alla sessione collaborativa",
"notifyRenamed": "{0} ha cambiato il suo nome in {1}",
"notifyLeft": "{0} ha abbandonato la sessione collaborativa",
"ok": "OK",
"okButton": "OK (Enter)",
"okButton": "OK (Invio)",
"cancel": "Annulla",
"cancelButton": "Cancella (Esc)",
"show_help_button": "Mostra l'aiuto",
"hide_help_button": "Nascondi l'aiuto",
"help_button": "Aiuto",
"cancelButton": "Annulla (Esc)",
"show_help_button": "Mostra la guida",
"hide_help_button": "Nascondi la guida",
"help_button": "Guida",
"historyText": "Cronologia",
"historyButton": "Mostra la cronologia di questo documento",
"historyButton": "Mostra la cronologia del documento",
"history_next": "Versione più recente",
"history_prev": "Versione più vecchia",
"history_prev": "Versione meno recente",
"history_loadMore": "Carica più cronologia",
"history_closeTitle": "Chiudi la cronologia",
"history_restoreTitle": "Ripristina la versione selezionata di questo documento",
"history_restorePrompt": "Sei sicuro di voler ripristinare la versione corrente con quella selezionata?",
"history_restoreTitle": "Ripristina la versione selezionata del documento",
"history_restorePrompt": "Sei sicuro di voler sostituire la versione corrente del documento con quella visualizzata?",
"history_restoreDone": "Documento ripristinato",
"history_version": "Versione:",
"openLinkInNewTab": "Apri link in una nuova pagina",
"openLinkInNewTab": "Apri link in una nuova scheda",
"pad_mediatagTitle": "Opzioni del Media-Tag",
"pad_mediatagWidth": "Larghezza (px)",
"pad_mediatagHeight": "Altezza (px)",
@ -211,12 +211,12 @@
"kanban_deleteBoard": "Sei sicuro di voler cancellare questa tabella?",
"kanban_addBoard": "Aggiungi una tabella",
"kanban_removeItem": "Rimuovi questo elemento",
"kanban_removeItemConfirm": "Sei sicuro di voler cancellare questo elemento?",
"kanban_removeItemConfirm": "Sei sicuro di voler eliminare questo elemento?",
"poll_title": "Selettore di date Zero Knowledge",
"poll_subtitle": "Pianificazione Zero Knowledge, in <em>tempo reale</em>",
"poll_p_save": "Le tue impostazioni sono aggiornata istantaneamente, quindi non c'è bisogno di salvarle.",
"poll_p_save": "Le tue impostazioni sono aggiornate istantaneamente, quindi non c'è bisogno di salvarle.",
"poll_p_encryption": "Tutto ciò che scrivi è criptato, quindi solo chi ha il link può accedervi. Nemmeno il server può vedere quello che cambi.",
"wizardLog": "Premi sul bottone in alto a sinistra per tornare al tuo sondaggio",
"wizardLog": "Clicca il pulsante in alto a sinistra per tornare al tuo sondaggio",
"wizardTitle": "Usa l'assistente per creare il tuo sondaggio",
"wizardConfirm": "Sei sicuro di voler aggiungere queste opzioni al tuo sondaggio?",
"poll_publish_button": "Pubblica",
@ -233,13 +233,13 @@
"poll_wizardAddTimeButton": "+ Orari",
"poll_optionPlaceholder": "Opzione",
"poll_userPlaceholder": "Il tuo nome",
"poll_removeOption": "Sei sicuro di voler cancellare questa opzione?",
"poll_removeOption": "Sei sicuro di voler eliminare questa opzione?",
"poll_removeUser": "Sei sicuro di voler rimuovere questo utente?",
"poll_titleHint": "Titolo",
"poll_descriptionHint": "Descrivi il tuo sondaggio e usa il bottone ✓ (Pubblica) quando hai finito.\nLa descrizione può essere scritta usando la sintassi markdown e può contenere elementi media dal tuo CryptDrive.\nChiunque sia in possesso del link può modificarne la descrizione, anche se ciò è sconsigliato.",
"poll_descriptionHint": "Descrivi il tuo sondaggio e usa il pulsante ✓ (Pubblica) quando hai finito.\nLa descrizione può essere scritta usando la sintassi markdown e può contenere elementi media dal tuo CryptDrive.\nChiunque sia in possesso del link può modificarne la descrizione, anche se ciò è sconsigliato.",
"poll_remove": "Rimuovi",
"poll_edit": "Modifica",
"poll_locked": "Chiuso",
"poll_locked": "Bloccato",
"poll_unlocked": "Sbloccato",
"poll_bookmark_col": "Marca questa colonna come preferita, così sarà sempre sbloccata e ti sarà mostrata per prima",
"poll_bookmarked_col": "Questa è la tua colonna preferita. Sarà sempre sbloccata e ti verrà mostrata per prima.",
@ -247,27 +247,27 @@
"poll_comment_list": "Commenti",
"poll_comment_add": "Aggiungi un commento",
"poll_comment_submit": "Invia",
"poll_comment_remove": "Cancella questo commento",
"poll_comment_remove": "Elimina questo commento",
"poll_comment_placeholder": "Il tuo commento",
"poll_comment_disabled": "Pubblica questo sondaggio usando il bottone ✓ per attivare i commenti.",
"oo_reconnect": "La connessione al server è tornata. Premi OK per ricaricare e continuare la modifica.",
"poll_comment_disabled": "Pubblica questo sondaggio usando il pulsante ✓ per attivare i commenti.",
"oo_reconnect": "La connessione al server è tornata. Clicca OK per ricaricare e continuare la modifica.",
"oo_cantUpload": "Impossibile importare un documento se altri utenti sono presenti.",
"oo_uploaded": "Il tuo upload è stato completato. Premi OK per ricaricare la pagina o cancella per continuare in modalità solo lettura.",
"oo_uploaded": "Il tuo caricamento è stato completato. Clicca OK per ricaricare la pagina o annulla per continuare in modalità solo lettura.",
"canvas_clear": "Pulisci",
"canvas_delete": "Cancella la selezione",
"canvas_delete": "Elimina la selezione",
"canvas_disable": "Disattiva il disegno",
"canvas_enable": "Attiva il disegno",
"canvas_width": "Larghezza",
"canvas_opacity": "Opacità",
"canvas_opacityLabel": "Opacità: {0}",
"canvas_widthLabel": "Larghezza: {0}",
"canvas_saveToDrive": "Salva l'immagine come file nel tuo CryptDrive",
"canvas_saveToDrive": "Salva questa immagine come file nel tuo CryptDrive",
"canvas_currentBrush": "Pennello attuale",
"canvas_chooseColor": "Scegli un colore",
"canvas_imageEmbed": "Inserisci una immagine dal tuo computer",
"canvas_imageEmbed": "Incorpora un'immagine dal tuo computer",
"profileButton": "Profilo",
"profile_urlPlaceholder": "URL",
"profile_namePlaceholder": "Nome mostrato nel profilo",
"profile_namePlaceholder": "Nome mostrato nel tuo profilo",
"profile_avatar": "Avatar",
"profile_upload": " Carica un nuovo avatar",
"profile_uploadSizeError": "Errore: il tuo avatar deve essere più piccolo di {0}",
@ -285,16 +285,16 @@
"contacts_rejected": "Invito ai contatti rifiutato",
"contacts_request": "<em>{0}</em> vorrebbe aggiungerti ai contatti. <b>Accettare<b>?",
"contacts_send": "Invia",
"contacts_remove": "RImuovi questo contatto",
"contacts_remove": "Rimuovi questo contatto",
"contacts_confirmRemove": "Sei sicuro di voler rimuovere <em>{0}</em> dai tuoi contatti?",
"contacts_typeHere": "Scrivi un messaggio qui...",
"contacts_warning": "Tutto ciò che scrivi qui è permanente e disponibile a tutti gli user esistenti e futuri di questo pad. Sii prudente con le tue informazioni personali!",
"contacts_warning": "Tutto ciò che scrivi qui è permanente e disponibile a tutti gli utenti esistenti e futuri di questo pad. Sii prudente con le tue informazioni personali!",
"contacts_padTitle": "Chat",
"contacts_info1": "Questi sono i tuoi contatti. Da qui, puoi:",
"contacts_info2": "Clicca sull'icona di un contatto per chattare con lui",
"contacts_info3": "Doppio-click sulla sua icona per vederne il profilo",
"contacts_info3": "Doppio-clic sulla sua icona per vederne il profilo",
"contacts_info4": "Qualsiasi partecipante può cancellare definitivamente la cronologia di una chat",
"contacts_removeHistoryTitle": "Cancellare la cronologia della chat",
"contacts_removeHistoryTitle": "Cancella la cronologia della chat",
"contacts_confirmRemoveHistory": "Sei sicuro di voler rimuovere permanentemente la cronologia della chat? I dati non possono essere recuperati",
"contacts_removeHistoryServerError": "C'è stato un errore nella cancellazione della cronologia della chat. Prova di nuovo più tardi",
"contacts_fetchHistory": "Recupera messaggi precedenti",
@ -313,11 +313,11 @@
"fm_searchName": "Cerca",
"fm_recentPadsName": "Pad recenti",
"fm_ownedPadsName": "Pad posseduti",
"fm_tagsName": "Tags",
"fm_tagsName": "Tag",
"fm_sharedFolderName": "Cartella condivisa",
"fm_searchPlaceholder": "Cerca...",
"fm_newButton": "Nuovo",
"fm_newButtonTitle": "Crea un nuovo pad o cartella, importa un file in questa cartella",
"fm_newButtonTitle": "Crea un nuovo pad o cartella, importa un file nella cartella corrente",
"fm_newFolder": "Nuova cartella",
"fm_newFile": "Nuovo pad",
"fm_folder": "Cartella",
@ -348,28 +348,28 @@
"fm_selectError": "Impossibile selezionare l'elemento desiderato. Se il problema persiste, prova a ricaricare la pagina.",
"fm_categoryError": "Impossibile aprire la categoria selezionata, mostro Documenti.",
"fm_info_root": "Crea quante cartelle desideri per contenere tutti i tuoi file.",
"fm_info_unsorted": "Contiene tutto i file che hai visitato che non sono stati ancora salvati in \"Documenti\" o spostati nel \"Cestino\".",
"fm_info_unsorted": "Contiene tutti i file che hai visitato che non sono stati ancora salvati in \"Documenti\" o spostati nel \"Cestino\".",
"fm_info_template": "Contiene tutti i pad salvati come modelli e che puoi riutilizzare per creare nuovi pad.",
"fm_info_recent": "Lista dei pad recentemente aperti o modificati.",
"fm_info_recent": "Questi pad sono stati recentemente aperti o modificati da te o da persone con le quali tu collabori.",
"fm_info_trash": "Svuota il tuo cestino per liberare spazio nel tuo CryptDrive.",
"fm_info_allFiles": "Contiene tutti i file da \"Documenti\", \"Non catalogati\", \"Cestino\". Non puoi muovere o cancellare file da qui.",
"fm_info_anonymous": "Non hai effettuato l'accesso, quindi i tuoi pad scadranno fra tre mesi (<a href=\"https://blog.cryptpad.fr/2017/05/17/You-gotta-log-in/\" target=\"_blank\">scopri di più</a>). Sono conservati nel tuo browser, quindi cancellando la cronologia potresti farli scomparire.<br><a href=\"/register/\">Registrati</a> o <a href=\"/login/\">Accedi</a> per conservarli permanentemente.<br>",
"fm_info_sharedFolder": "Questa è una cartella condivisa. Non sei loggato, quindi puoi accederla solo in modalità solo lettura.<br><a href=\"/register/\">Registrati</a> o <a href=\"/login/\">Effettua il login</a> per poterla importare nel tuo CryptDrive e per modificarla.",
"fm_info_owned": "Sei il proprietario dei pad mostrati qui. Questo significa che puoi rimuoverli permanentemente dal server, quando lo desideri. Se lo fai, gli altri utenti non potranno più accedervi.",
"fm_info_sharedFolder": "Questa è una cartella condivisa. Non hai effettuato l'accesso, quindi puoi visualizzarla solo in modalità di sola lettura.<br><a href=\"/register/\">Registrati</a> o <a href=\"/login/\">Accedi</a> per poterla importare nel tuo CryptDrive e per modificarla.",
"fm_info_owned": "Sei il proprietario dei pad mostrati qui. Questo significa che puoi rimuoverli permanentemente dal server quando lo desideri. Se lo fai, gli altri utenti non potranno più accedervi.",
"fm_alert_backupUrl": "Link di backup per questo drive.<br>È<strong>estremamente raccomandato</strong> che tu lo tenga segreto.<br>Puoi usarlo per recuperare tutti i tuoi file nel caso in cui la memoria del tuo browser venga cancellata.<br>Chiunque in possesso di questo link può modificare o rimuovere tutti i file nel tuo file manager.<br>",
"fm_backup_title": "Link di backup",
"fm_nameFile": "Come vuoi chiamare questo file?",
"fm_error_cantPin": "Errore interno del server. Per favore, ricarica la pagina e prova di nuovo.",
"fm_viewListButton": "Visualizzazione lista",
"fm_error_cantPin": "Errore interno del server. Ricarica la pagina e prova di nuovo.",
"fm_viewListButton": "Visualizzazione elenco",
"fm_viewGridButton": "Visualizzazione griglia",
"fm_renamedPad": "Hai impostato un nome personalizzato per questo pad. Il suo titolo condiviso è: <br><b>{0}</b>",
"fm_canBeShared": "Questa cartella può essere condivisa",
"fm_prop_tagsList": "Tags",
"fm_burnThisDriveButton": "Cancella tutte le informazioni salvate da CryptPad nel tuo browser",
"fm_prop_tagsList": "Tag",
"fm_burnThisDriveButton": "Elimina tutte le informazioni salvate da CryptPad nel tuo browser",
"fm_burnThisDrive": "Sei sicuro di voler rimuovere tutti i dati salvati da CryptPad nel tuo browser?<br>Questo rimuoverà il tuo CryptDrive e la sua cronologia dal tuo browser, ma i tuoi pad continueranno a esistere (criptati) nel nostro server.",
"fm_padIsOwned": "Sei il proprietario di questo pad",
"fm_padIsOwnedOther": "Il proprietario di questo pad è un altro user",
"fm_deletedPads": "Questi pads non esistono più sul server, sono stati rimossi dal tuo CryptDrive: {0}",
"fm_padIsOwnedOther": "Questo pad è di proprietà di un altro utente",
"fm_deletedPads": "Questi pad non esistono più sul server, sono stati rimossi dal tuo CryptDrive: {0}",
"fm_tags_name": "Nome del tag",
"fm_tags_used": "Numero di utilizzi",
"fm_restoreDrive": "Ripristina il tuo drive ad uno stato precedente. Per i migliori risultati, evita di fare cambiamenti al tuo drive sinchè questo processo non sarà completato.",
@ -379,45 +379,45 @@
"fc_newsharedfolder": "Nuova cartella condivisa",
"fc_rename": "Rinomina",
"fc_open": "Apri",
"fc_open_ro": "Apri (solo lettura)",
"fc_delete": "Muovi nel cestino",
"fc_delete_owned": "Cancella dal server",
"fc_open_ro": "Apri (sola lettura)",
"fc_delete": "Sposta nel cestino",
"fc_delete_owned": "Elimina dal server",
"fc_restore": "Ripristina",
"fc_remove": "Rimuovi dal tuo CryptDrive",
"fc_remove_sharedfolder": "Rimuovi",
"fc_empty": "Svuota il cestino",
"fc_prop": "Proprietà",
"fc_hashtag": "Tags",
"fc_sizeInKilobytes": "Dimensione in Kilobytes",
"fo_moveUnsortedError": "Non puoi muovere una cartella nella lista dei modelli",
"fo_existingNameError": "Il nome è già utilizzato in questa cartella. Per favore, scegline un altro.",
"fo_moveFolderToChildError": "Non puoi muovere una cartella in una contenuta in essa",
"fo_unableToRestore": "Impossibile ripristinare questo file nella sua location originaria. Puoi provare a muoverlo in una nuova posizione.",
"fo_unavailableName": "Un file o una cartella con lo stesso nome esiste già nella nuova posizione. Rinomina l'elemento e prova di nuovo.",
"fs_migration": "Il tuo CryptDrive sta per essere aggiornato a una nuova versione. La pagina corrente sarà ricaricata.<br><strong>Per favore, ricarica la pagina per continuare a usarla.</strong>",
"login_login": "Login",
"login_makeAPad": "Crea un pad in maniera anonima",
"login_nologin": "Sfoglia i pads locali",
"fc_hashtag": "Tag",
"fc_sizeInKilobytes": "Dimensione in Kilobyte",
"fo_moveUnsortedError": "Non puoi spostare una cartella nell'elenco dei modelli",
"fo_existingNameError": "Il nome è già utilizzato in questa cartella. Scegline un altro.",
"fo_moveFolderToChildError": "Non puoi spostare una cartella in una contenuta in essa",
"fo_unableToRestore": "Impossibile ripristinare questo file nella sua posizione originaria. Puoi provare a spostarlo in una nuova posizione.",
"fo_unavailableName": "Un file o una cartella con lo stesso nome esiste già nella nuova posizione. Rinomina l'elemento e riprova.",
"fs_migration": "Il tuo CryptDrive sta per essere aggiornato ad una nuova versione. La pagina corrente sarà ricaricata.<br><strong>Ricarica la pagina per continuare ad usarla.</strong>",
"login_login": "Accedi",
"login_makeAPad": "Crea un pad in modalità anonima",
"login_nologin": "Sfoglia i pad locali",
"login_register": "Registrati",
"logoutButton": "Logout",
"logoutButton": "Esci",
"settingsButton": "Impostazioni",
"login_username": "Nome utente",
"login_password": "Password",
"login_confirm": "Conferma la tua password",
"login_remember": "Ricorda l'accesso",
"login_remember": "Ricordami",
"login_hashing": "Effettuo l'hash della tua password, questo può richiedere del tempo.",
"login_hello": "Buongiorno {0},",
"login_hello": "Ciao {0},",
"login_helloNoName": "Ciao,",
"login_accessDrive": "Accedi al tuo drive",
"login_orNoLogin": "o",
"login_noSuchUser": "Nome utente o password non validi. Prova di nuovi, oppure registrati",
"login_noSuchUser": "Nome utente o password non validi. Prova di nuovo, oppure registrati",
"login_invalUser": "Nome utente richiesto",
"login_invalPass": "Password richiesta",
"login_unhandledError": "Si è verificato un errore inaspettato :(",
"register_importRecent": "Importa i pads dalla tua sessione anonima",
"register_importRecent": "Importa i pad dalla tua sessione anonima",
"register_acceptTerms": "Accetto <a href='/terms.html' tabindex='-1'>i termini del servizio</a>",
"register_passwordsDontMatch": "Le passwords non corrispondono!",
"register_passwordTooShort": "Le passwords devono essere lunghe almeno {0} caratteri.",
"register_passwordsDontMatch": "Le password non corrispondono!",
"register_passwordTooShort": "Le password devono essere lunghe almeno {0} caratteri.",
"register_mustAcceptTerms": "Devi accettare i termini del servizio.",
"register_mustRememberPass": "Non possiamo ripristinare la tua password se la dimentichi. È estremamente importante che tu la ricordi! Per favore, spunta la checkbox per confermare.",
"register_whyRegister": "Perché registrarsi?",
@ -426,7 +426,7 @@
"register_writtenPassword": "Ho annotato il mio nome utente e la mia password, procedi",
"register_cancel": "Torna indietro",
"register_warning": "Zero Knowledge significa che non possiamo recuperare i tuoi dati se perdi la tua password.",
"register_alreadyRegistered": "Questo utente esiste già, vuoi effettuare il log in?",
"register_alreadyRegistered": "Questo utente esiste già, vuoi accedere?",
"settings_cat_account": "Account",
"settings_cat_drive": "CryptDrive",
"settings_cat_cursor": "Cursore",
@ -440,59 +440,59 @@
"settings_backupHint": "Effettua il backup o importane uno con tutto il contenuto del tuo CryptDrive. Non conterrà il contenuto dei pads, solo le chiavi per potervi accedere.",
"settings_backup": "Backup",
"settings_restore": "Importa",
"settings_backupHint2": "Scarica il contenuto corrente dei tuoi pads. I pads saranno scaricati in un formato leggibile, se possibile.",
"settings_backupHint2": "Scarica il contenuto corrente dei tuoi pad. I pad saranno scaricati in un formato leggibile, se possibile.",
"settings_backup2": "Scarica il mio CryptDrive",
"settings_backup2Confirm": "Questo scaricherà tutti i tuoi pad e files dal tuo CryptDrive. Se vuoi continuare, scegli un nome e premi OK",
"settings_backup2Confirm": "Questo scaricherà tutti i tuoi pad e file dal tuo CryptDrive. Se vuoi continuare, scegli un nome e premi OK",
"settings_exportTitle": "Esporta il tuo CryptDrive",
"settings_exportDescription": "Per favore attendi mentre scarichiamo e decriptiamo i tuoi documenti. Potrebbe richiedere qualche minuto. Chiudere la finestra interromperà il processo.",
"settings_exportFailed": "Se il pad richiede più di un minuto per essere scaricato, non sarà incluso nell'export. Un link a qualsiasi pad non esportato sarà mostrato.",
"settings_exportWarning": "Nota bene: questo strumento è ancora in versione beta e può presentare problemi di scalabilità. Per migliorare le prestazioni, è consigliabile lasciare attiva questa tab.",
"settings_exportCancel": "Sei sicuro di voler cancellare l'export? Dovrai iniziare da capo la prossima volta.",
"settings_exportFailed": "Se un pad richiede più di un minuto per essere scaricato, non sarà incluso nell'esportazione. Un link a qualsiasi pad non esportato sarà mostrato.",
"settings_exportWarning": "Nota bene: questo strumento è ancora in versione beta e può presentare problemi di scalabilità. Per migliorare le prestazioni, è consigliabile lasciare attiva questa scheda.",
"settings_exportCancel": "Sei sicuro di voler annullare l'esportazione? Dovrai iniziare da capo la prossima volta.",
"settings_export_reading": "Lettura del tuo CryptDrive in corso...",
"settings_export_download": "Scaricamento e decriptazione dei tuoi documenti in corso...",
"settings_export_compressing": "Compressione dei dati in corso...",
"settings_export_done": "Il tuo download è pronto!",
"settings_exportError": "Visualizza errori",
"settings_exportErrorDescription": "Non siamo riusciti ad aggiungere i seguenti documenti all'export:",
"settings_exportErrorEmpty": "Questo documento non può essere esportato (contenuto vuoto o invalido).",
"settings_exportError": "Visualizza gli errori",
"settings_exportErrorDescription": "Non siamo riusciti ad aggiungere i seguenti documenti all'esportazione:",
"settings_exportErrorEmpty": "Questo documento non può essere esportato (contenuto vuoto o non valido).",
"settings_exportErrorMissing": "Questo documento non è stato trovato nei nostri server (scaduto o rimosso dal suo proprietario)",
"settings_exportErrorOther": "È accaduto un errore durante l'esportazione di questo documento: {0}",
"settings_exportErrorOther": "Si è verificato un errore durante l'esportazione di questo documento: {0}",
"settings_resetNewTitle": "Pulisci CryptDrive",
"settings_resetButton": "Rimuovi",
"settings_reset": "Rimuovi tutti i file e le cartelle dal tuo CryptDrive",
"settings_resetPrompt": "Questa azione eliminerà tutti i pad del tuo drive.<br>Sei sicuro di vole continuare?<br>Digita “<em>I love CryptPad</em>” per confermare.",
"settings_resetDone": "Il tuo drive è vuoto adesso!",
"settings_resetPrompt": "Questa azione eliminerà tutti i pad dal tuo drive.<br>Sei sicuro di vole continuare?<br>Digita “<em>I love CryptPad</em>” per confermare.",
"settings_resetDone": "Il tuo drive adesso è vuoto!",
"settings_resetError": "Testo di verifica errato. Il tuo CryptDrive non è stato modificato.",
"settings_resetTipsAction": "Ripristinare",
"settings_resetTips": "Suggerimenti",
"settings_resetTipsButton": "Ripristinare i suggerimenti disponibili in CryptDrive",
"settings_resetTipsDone": "Ora tutti i suggerimenti sono di nuovo visibili.",
"settings_thumbnails": "Miniature",
"settings_disableThumbnailsAction": "Disattivare la creazione di miniature nel tuo CryptDrive",
"settings_disableThumbnailsDescription": "Le miniature sono create automaticamente e conservate nel tuo browser. Puoi disattivare questa funzione qui.",
"settings_disableThumbnailsAction": "Disattiva la creazione di miniature nel tuo CryptDrive",
"settings_disableThumbnailsDescription": "Le miniature sono create automaticamente e conservate nel tuo browser quando visiti un nuovo pad. Qui puoi disattivare questa funzione.",
"settings_resetThumbnailsAction": "Pulire",
"settings_resetThumbnailsDescription": "Pulire tutte le miniature conservate nel browser.",
"settings_resetThumbnailsDone": "Tutte le miniature sono state cancellate.",
"settings_resetThumbnailsDescription": "Pulisci tutte le miniature dei pad conservate nel tuo browser.",
"settings_resetThumbnailsDone": "Tutte le miniature sono state eliminate.",
"settings_import": "Importa",
"settings_importConfirm": "Sei sicuro di voler importare i tuoi pads recenti dal browser sul tuo account CryptDrive?",
"settings_importConfirm": "Sei sicuro di voler importare i tuoi pad recenti da questo browser sul tuo account CryptDrive?",
"settings_autostoreMaybe": "Manuale (chiedi sempre)",
"settings_userFeedbackTitle": "Feedbacks",
"settings_userFeedbackTitle": "Feedback",
"settings_userFeedbackHint1": "CryptPad fornisce solo alcuni feedback basilari al server, per aiutarci a migliorare la tua esperienza. ",
"settings_userFeedbackHint2": "Il contenuto dei tuoi pads non sarà mai condiviso con il server.",
"settings_userFeedback": "Abilita feedback dell'user",
"settings_deleteTitle": "Cancella account",
"settings_deleteHint": "La cancellazione dell'account è permanente. Il tuo CryptDrive e la tua lista di pads sarà cancellata dal server. Il resto dei tuoi pads sarà cancellato in 90 giorni se nessun altro li ha salvati nel suo CryptDrive.",
"settings_userFeedbackHint2": "Il contenuto del tuo pad non sarà mai condiviso con il server.",
"settings_userFeedback": "Abilita feedback dell'utente",
"settings_deleteTitle": "Cancellazione account",
"settings_deleteHint": "La cancellazione dell'account è permanente. Il tuo CryptDrive e il tuo elenco di pad sarà cancellato dal server. Il resto dei tuoi pad sarà eliminato in 90 giorni se nessun altro li ha salvati nel suo CryptDrive.",
"settings_deleteButton": "Cancella il tuo account",
"padNotPinnedVariable": "Questo pad scadrà dopo {4} giorni di inattività, {0}accedi{1} o {2}registrati{3} per conservarlo.",
"storageStatus": "Spazio:<br />1<b>2{0}</b>3 usati di <b>4{1}</b>5",
"uploadFolderButton": "Cartella upload",
"uploadFolderButton": "Carica cartella",
"fm_morePads": "Altro",
"fc_color": "Cambia colore",
"fc_openInCode": "Apri nell'editor di codice",
"fc_expandAll": "Espandi tutto",
"fc_collapseAll": "Comprimi tutto",
"register_emailWarning0": "Sembra che tu abbia inserito la tua email come nome utente.",
"settings_driveDuplicateHint": "Quando sposti i tuoi pad in una cartella condivisa, una copia è conservata nel tuo CryptDrive per assicurartene il controllo. Puoi nascondere i file duplicati. Soltanto la versione condivisa verrà mostrata, a meno che non venga eliminata: in tal caso il file originale verrà mostrato nella sua posizione precedente.",
"settings_driveDuplicateHint": "Quando sposti i tuoi pad in una cartella condivisa, una copia è conservata nel tuo CryptDrive per assicurartene il controllo. Puoi nascondere i file duplicati. Soltanto la versione condivisa verrà mostrata, a meno che non venga eliminata, in tal caso il file originale verrà mostrato nella sua posizione precedente.",
"settings_codeIndentation": "Indentazione dell'editor di codice (spazi)",
"settings_codeFontSize": "Dimensione del testo dell'editor di codice",
"uploadFolder_modal_filesPassword": "Password dei file",
@ -501,29 +501,55 @@
"upload_mustLogin": "Devi eseguire l'accesso per poter caricare file",
"pad_base64": "Questo pad contiene immagini conservate in maniera inefficiente. Queste immagini aumenteranno significativamente le dimensioni del pad nel tuo CryptDrive, e lo renderanno più lento da caricare. Puoi convertire questi file in un nuovo formato che verrà conservato separatamente nel tuo CryptDrive. Vuoi convertire queste immagini ora?",
"mdToolbar_code": "Codice",
"home_host": "Questa è un'istanza di CryptPad gestita indipendentemente dalla community. Il suo codice sorgente è disponibile <a href=\"https://github.com/xwiki-labs/cryptpad\" target=\"_blank\" rel=\"noreferrer noopener\">su GitHub</a>2.",
"whatis_drive_p3": "Puoi anche caricare file nel tuo CryptDrive e condividerli coi colleghi. I file caricati possono essere organizzati proprio come i pad collaborativi.",
"home_host": "Questa è un'istanza di CryptPad gestita indipendentemente dalla community. Il suo codice sorgente è disponibile <a href=\"https://github.com/xwiki-labs/cryptpad\" target=\"_blank\" rel=\"noreferrer noopener\">su GitHub</a>.",
"whatis_drive_p3": "Puoi anche caricare file nel tuo CryptDrive e condividerli con i colleghi. I file caricati possono essere organizzati proprio come i pad collaborativi.",
"policy_choices_open": "Il nostro codice sorgente è open source, così hai sempre la possibilità di ospitare la tua personale istanza di CryptPad.",
"features_f_file0": "Apri file",
"features_f_file0": "Apri i file",
"help": {
"slide": {
"markdown": "Scrivi diapositive in <a href=\"http://www.markdowntutorial.com/\">Markdown</a> e separale con una linea contente <code>---</code>"
"markdown": "Scrivi diapositive in <a href=\"http://www.markdowntutorial.com/\">Markdown</a> e separale con una linea contente <code>---</code>",
"present": "Inizia la presentazione usando il pulsante <span class=\"fa fa-play-circle\"></span>",
"colors": "Cambia i colori di testo e sfondo usando i pulsanti <span class=\"fa fa-i-cursor\"></span> e <span class=\"fa fa-square\"></span>"
},
"pad": {
"export": "Puoi esportare il contenuto come PDF usando il pulsante <span class=\"fa fa-print\"></span> nella barra degli strumenti di formattazione"
},
"text": {
"history": "Puoi usare <em>la cronologia</em> <span class=\"fa fa-history\"></span> per vedere o ripristinare le versioni precedenti",
"embed": "Gli utenti registrati possono incorporare un'immagine o un file salvato nel loro CryptDrive usando <span class=\"fa fa-image\"></span>",
"formatting": "Puoi visualizzare o nascondere la barra degli strumenti di formattazione cliccando i pulsanti <span class=\"fa fa-caret-down\"></span> o <span class=\"fa fa-caret-up\"></span>"
},
"generic": {
"save": "Tutte le tue modifiche sono sincronizzate automaticamente, quindi non hai bisogno di salvare",
"share": "Usa il menu condividi (<span class=\"fa fa-shhare-alt\"></span>) per generare un link che permetta ai tuoi collaboratori di vedere o modificare questo pad",
"more": "Impara di più su cosa può fare CryptPad per te leggendo le nostre <a href=\"/faq.html\" target=\"_blank\">FAQ</a>"
},
"title": "Cominciamo",
"oo": {
"access": "L'accesso è riservato agli utenti registrati, i collaboratori devono accedere"
},
"whiteboard": {
"colors": "Fai doppio clic sui colori per modificare la tua palette"
},
"poll": {
"submit": "Clicca <strong>invia</strong> per rendere le tue scelte visibili agli altri"
}
},
"readme_cat3_l1": "Con l'editor di codice di CryptPad, puoi collaborare su linguaggi di programmazione come Javascript e linguaggi di markup come HTML o Markdown",
"settings_codeSpellcheckLabel": "Abilita la revisione ortografica nell'editor di codice",
"settings_codeSpellcheckLabel": "Abilita il controllo ortografico nell'editor di codice",
"team_inviteLinkError": "Si è verificato un errore durante la creazione del link.",
"register_emailWarning1": "Puoi farlo se vuoi, ma non verrà inviato ai nostri server.",
"register_emailWarning2": "Non sarai in grado di resettare la tua password usando la tua email, a differenza di come puoi fare con molti altri servizi.",
"register_emailWarning3": "Se hai capito, ma intendi comunque usare la tua email come nome utente, clicca OK.",
"oo_sheetMigration_anonymousEditor": "Le modifiche da parte di utenti anonimi a questo foglio di calcolo sono disabilitate finchè un utente registrato non lo aggiorna all'ultima versione.",
"oo_sheetMigration_anonymousEditor": "Le modifiche da parte di utenti anonimi a questo foglio di calcolo sono disabilitate finché un utente registrato non lo aggiorna all'ultima versione.",
"faq": {
"usability": {
"devices": {
"a": "È probabile che tu abbia registrato lo stesso nome due volte, usando password diverse. Poiché il server di CryptPad ti identifica usando la tua firma crittografica e non il tuo nome, non può impedire ad altre persone di registrarsi con lo stesso nome. Questo significa che ogni account ha una combinazione univoca di nome utente e password. Gli/le utenti registrati/e possono vedere il loro nome utente nella parte superiore della pagina delle impostazioni."
"a": "È probabile che tu abbia registrato lo stesso nome due volte, usando password diverse. Poiché il server di CryptPad ti identifica usando la tua firma crittografica e non il tuo nome, non può impedire ad altre persone di registrarsi con lo stesso nome. Questo significa che ogni account utente ha una combinazione univoca di nome utente e password. Gli utenti connessi possono vedere il loro nome utente nella parte superiore della pagina delle impostazioni.",
"q": "Sono connesso con due dispositivi e vedo due diversi CryptDrive, com'è possibile?"
},
"forget": {
"a": "Purtroppo, se fossimo in grado di aiutarti a recuperare l'accesso ai tuoi pad criptati, saremmo noi stessi/e in grado di accedere ai tuoi pad. Se non hai salvato il tuo nome utente e password da nessuna parte e non resci a ricordarli, potresti essere in grado di recuperare i tuoi pad controllando la cronologia del browser.",
"a": "Purtroppo, se fossimo in grado di aiutarti a recuperare l'accesso ai tuoi pad criptati, saremmo noi stessi in grado di accedere ai tuoi pad. Se non hai salvato il tuo nome utente e la password da nessuna parte e non riesci a ricordarli, potresti essere in grado di recuperare i tuoi pad controllando la cronologia del browser.",
"q": "Cosa succede se dimentico la mia password?"
},
"change": {
@ -531,23 +557,43 @@
"q": "E se voglio modificare la mia password?"
},
"register": {
"q": "Cosa ottengo registrandomi?"
"q": "Cosa ottengo registrandomi?",
"a": "Gli utenti registrati hanno accesso ad alcune funzionalità non disponibili a chi non è registrato. C'è uno schema <a href='/features.html' target='_blank'>qui</a>."
},
"title": "Usabilità"
"title": "Usabilità",
"feature": {
"a": "Molte delle funzionalità in CryptPad esistono perché gli utenti le hanno richieste. La nostra <a href='https://cryptpad.fr/contact.html' target='_blank'>pagina di contatto</a> elenca i modi che puoi usare per raggiungerci.<br><br>Sfortunatamente, non possiamo garantire che aggiungeremo tutto quello che la gente chiede. Se una particolare funzionalità è essenziale per la tua organizzazione, puoi sponsorizzare il tempo di sviluppo per garantire il suo completamento. Contatta <a href='mailto:sales@cryptpad.fr' target='_blank'>sales@cryptpad.fr</a> per ulteriori informazioni.<br><br>Anche se non puoi permetterti di sponsorizzare lo sviluppo, siamo interessati ai feedback che possono aiutarci a migliorare CryptPad. Sentiti libero di contattarci tramite uno dei modi indicati in qualsiasi momento.",
"q": "Potete aggiungere una funzionalità particolare di cui ho bisogno?"
},
"folder": {
"a": "Si, puoi creare una <em>cartella condivisa</em> nel tuo CryptDrive e così condividere tutti i pad che contiene.",
"q": "Posso condividere intere cartelle dal mio CryptDrive?"
},
"remove": {
"a": "Solo i <em>pad proprietari</em> (introdotto nel febbraio 2018) possono essere cancellati. In aggiunta, questi pad possono essere cancellati solo dal loro <em>proprietario</em> (la persona che inizialmente ha creato il pad). Se non sei il creatore del pad, dovrai chiedere al suo titolare di cancellarlo. Per i pads di cui sei titolare, puoi <strong>cliccare con il tasto destro il pad nel tuo CryptDrive</strong>, e scegliere <strong>Cancella dal server</strong>.",
"q": "Ho rimosso un pad o un file dal mio CryptDrive, ma il contenuto è ancora disponibile. Come posso rimuoverlo?"
},
"share": {
"a": "CryptPad mette la chiave di crittografia segreta sul tuo pad dopo il carattere <em>#</em> nell'URL. Tutto quello che segue questo carattere non viene inviato al server, quindi non abbiamo accesso alla tua chiave di crittografia. Condividendo il link a un pad condividi anche la possibilità di accedervi e leggerlo.",
"q": "Come posso condividere i pad crittografati con i miei contatti?"
}
},
"security": {
"crypto": {
"a": "CryptPad è basato su due librerie open-source di crittografia: <a href='https://github.com/dchest/tweetnacl-js' target='_blank'>tweetnacl.js</a> and <a href='https://github.com/dchest/scrypt-async-js' target='_blank'>scrypt-async.js</a>.<br><br>Scrypt è un <em>algoritmo di derivazione delle chiavi basato su password</em>. Lo utilizziamo per trasformare i tuoi username e password in una chiave unica che assicura l'accesso al tuo CryptDrive così che solo tu possa accedere ai tuoi pad.<br><br>Utilizziamo i crypters <em>xsalsa20-poly1305</em> e <em>x25519-xsalsa20-poly1305</em> forniti da tweetnacl rispettivamente per criptare i pad e la chat.",
"a": "CryptPad è basato su due librerie open-source di crittografia: <a href='https://github.com/dchest/tweetnacl-js' target='_blank'>tweetnacl.js</a> e <a href='https://github.com/dchest/scrypt-async-js' target='_blank'>scrypt-async.js</a>.<br><br>Scrypt è un <em>algoritmo di derivazione delle chiavi basato su password</em>. Lo utilizziamo per trasformare i tuoi nome utente e password in una chiave unica che assicura l'accesso al tuo CryptDrive così che solo tu possa accedere ai tuoi pad.<br><br>Utilizziamo i cifrari <em>xsalsa20-poly1305</em> e <em>x25519-xsalsa20-poly1305</em> forniti da tweetnacl rispettivamente per criptare i pad e la cronologia della chat.",
"q": "Quale crittografia utilizzate?"
},
"pad_password": {
"q": "Coda succede quando proteggo un pad/cartella con una password?"
"q": "Cosa succede quando proteggo un pad/cartella con una password?",
"a": "Puoi proteggere qualsiasi pad o cartella condivisa con una password quando li crei. Puoi anche usare il menu Proprietà in qualsiasi momento per impostare/cambiare/rimuovere una password.<br><br>Le password dei pad e delle cartelle condivise sono finalizzate a proteggere i link quando li condividi su canali potenzialmente non sicuri come la mail o i messaggi di testo. Se qualcuno intercettasse il tuo link ma non disponesse della password non sarebbe comunque in grado di leggere il tuo documento.<br><br>Quando condividi all'interno di CryptPad con i tuoi contatti o il tuo gruppo, le comunicazioni sono crittografate e noi presumiamo che tu voglia che questi accedano al tuo documento. In ogni caso la password è memorizzata ed inviata con il documento quando lo condividi. All'autore, o a te, <b>non</b> verrà richiesta quando si apre il documento."
},
"compromised": {
"q": "CryptPad mi protegge se il mio dispositivo è compromesso?"
"q": "CryptPad mi protegge se il mio dispositivo è compromesso?",
"a": "Nel caso in cui un tuo device sia stato rubato, CryptPad ti permette di attivare il remote logout (disconnessione forzata in remoto) di tutti i device a parte quello che stai utilizzando. Per farlo, vai sulla tua <strong>settings page</strong> e clicca <strong>Disconnetti ovunque</strong>. Tutte le altre device che sono attualmente connesse al tuo account saranno disconnesse. Tutte le device che si sono connesse in precedenza al tuo CryptPad saranno sconnesse appena si collegheranno alla pagina.<br><br>Attualmente, <em>Logout remoto</em> è implemetato nel browser, non in connessione con il server. Quindi non può proteggerti da agenzie governative, ma può essere sufficiente se dimentichi di sconnetterti dopo aver usato CryptPad da un computer condiviso."
},
"why": {
"q": "Perché dovrei usare CryptPad?"
"q": "Perché dovrei usare CryptPad?",
"a": "La nostra opinione è che i servizi cloud non debbano richiedere accesso ai tuoi dati perché tu possa condividerli con amici e colleghi. Se stai usando un altro servizio per collaborare e questo non dichiara esplicitamente che non può accedere ai tuoi dati, è verosimile che li stia gestendo per profitto."
},
"title": "Sicurezza",
"proof": {
@ -561,7 +607,7 @@
},
"policy": {
"a": "Sì! È disponibile <a href='/privacy.html' target='_blank'>qui</a>.",
"q": "Avete una politica di privacy dei dati?"
"q": "Avete una politica per la privacy dei dati?"
},
"title": "Privacy",
"anonymous": {
@ -570,7 +616,7 @@
},
"other": {
"q": "Cosa possono conoscere di me gli altri collaboratori?",
"a": "Quando lavorate su un pad insieme ad altri, comunicate attraverso il server, l'unica informazione raccolta è il vostro indirizzo IP. Gli altri possono vedere il vostro nome utente, l'avatar, un link al vostro profilo (se ne avete uno), e la vostra <em>chiave pubblica</em> (che è utilizzata per criptare le informazioni dall'uno all'altro)."
"a": "Quando modifichi su un pad insieme ad altri comunichi attraverso il server, così conosciamo il tuo indirizzo IP. Gli altri utenti possono vedere il tuo nome utente, l'avatar, un link al tuo profilo (se ne hai uno), e la tua <em>chiave pubblica</em> (che è utilizzata per criptare le informazioni dall'uno all'altro)."
},
"me": {
"q": "Che informazioni ha il server su di me?",
@ -587,21 +633,31 @@
"q": "Assumete?"
},
"goal": {
"q": "Qual è il vostro obiettivo?"
"q": "Qual è il vostro obiettivo?",
"a": "Sviluppando una tecnologia rispettosa della privacy, vogliamo anche incrementare le aspettative degli utenti relativamente al rapporto tra privacy e cloud computing. Speriamo che il nostro lavoro spinga altri fornitori di servizi in tutti gli ambiti ad eguagliare il nostro sforzo o superarlo. Nonostante il nostro ottimismo, sappiamo che la gran parte del web asa il suo gettito sulla pubblicità targettizzata. C'è molto più lavoro da fare di quanto possiamo pensare di gestire noi stessi, e dunque apprezziamo l'incoraggiamento, il sostegno ed il contributo della nostra community per il raggiungimento di questo obiettivo."
},
"pay": {
"q": "Perché dovrei pagare quando così tante funzionalità sono gratuite?"
"q": "Perché dovrei pagare quando così tante funzionalità sono gratuite?",
"a": "Diamo ai supporters spazio di archiviazione aggiuntivo e la possibilità di incrementare la loro quota di contatti (<a href='https://accounts.cryptpad.fr/#/faq' target='_blank'>approfondisci</a>).<br><br>Oltre a questi benefici a breve termine, sottoscrivendo un account premium aiuti a finanziare in maniera continuativa, lo sviluppo attivo di CryptPad. Questo include l'eliminazione di bugs, l'aggiunta di nuove funzionalità, e semplificare per altri la diffusione di CryptPad. Inoltre, aiuti a mostrare agli altri service providers che le persone sono disposte a supportare le tecnologie per il miglioramento della privacy. Noi speriamo che i modelli di business basati sulla vendita dei dati degli utenti diventeranno cosa del passato.<br><br>Infine, offriamo la maggior parte delle funzionalità di CryptPad gratuitamente perché crediamo che everyone meritino la privacy, non solo chi può permettersela. Supportandoci, ci aiuti a continuare a rendere possibile alla popolazione con meno privilegi di accedere a funzionalità fondamentali senza il cartellino del prezzo attaccato."
},
"title": "Altre domande"
"title": "Altre domande",
"revenue": {
"a": "Se hai implementato la tua istanza di CryptPad, e vuoi attivare il agamento dei servizi e dividerlo con la community degli sviluppatori, il tuo server dovrà essere configurato come partner service.<br><br>Nella cartella di CryptPad, <em>config.example.js</em> contiene una spiegazione di cosa hai bisogno di configurare sul tuo server. Avrai anche bisogno di contattare <a href='mailto:sales@cryptpad.fr'>sales@cryptpad.fr</a> per verificare che nel tuo server sia configurato correttamente HTTPS, e per concordare i metodi di pagamento.",
"q": "Come posso contribuire alla compartecipazione alle entrate?"
},
"host": {
"a": "Siamo lieti di fornire supporto per una installazione di CryptPad interna alla vostra organizzazione. Si prega di contattare <a href='mailto:sales@cryptpad.fr' target='_blank'>sales@cryptpad.fr</a> per maggiori informazioni.",
"q": "Potete aiutarmi a configurare la mia istanza di CryptPad?"
}
},
"keywords": {
"tag": {
"q": "Come utilizzo i tag?",
"a": "Puoi taggare i file creati o caricati con il tuo CryptDrive, oppure utilizzando il pulsante <em>tag</em> (<span class='fa fa-hashtag'></span>) nella barra degli strumenti di qualsiasi editor. Cerca gli appunti ed i file nel tuo CryptDrive utilizzando la barra di ricerca con una parola marcata come hashtag, ad esempio <em>#crypto</em>."
"a": "Puoi taggare i pad e i file caricati con il tuo CryptDrive, oppure utilizzando il pulsante <em>tag</em> (<span class='fa fa-hashtag'></span>) nella barra degli strumenti di qualsiasi editor. Cerca i pad ed i file nel tuo CryptDrive utilizzando la barra di ricerca con una parola preceduta da un cancelletto, ad esempio <em>#crypto</em>."
},
"pad": {
"q": "Cos'è un pad?",
"a": "<em>Pad</em> è un termine popolare per <a href='http://etherpad.org/' target='_blank'>Etherpad</a>, un editor collaborativo in tempo reale.\nSi riferisce ad un documento che puoi modificare nel tuo browser, generalmente con le modifiche di altri utenti visibili in modo quasi istantaneo."
"a": "<em>Pad</em> è un termine reso popolare da <a href='http://etherpad.org/' target='_blank'>Etherpad</a>, un editor collaborativo in tempo reale.\nSi riferisce ad un documento che puoi modificare nel tuo browser, generalmente con le modifiche di altri utenti visibili in modo quasi istantaneo."
},
"expiring": {
"q": "Cos'è un pad effimero?",
@ -618,7 +674,7 @@
},
"template": {
"q": "Cos'è un modello?",
"a": "Un template (modello) è un file che può essere usato per definire il contenuto iniziale per altri dello stesso tipo quando li crei. Qualsiasi salvataggio esistente può essere trasformato in un template spostandolo nella sezione <em>Template</em> del tuo CryptDrive. Puoi anche creare una copia di un pad da utilizzare come template cliccando il pulsante template (<span class='fa fa-bookmark'></span>) nella barra degli strumenti dell'editor."
"a": "Un modello è un pad che può essere usato per definire il contenuto iniziale per un altro pad dello stesso tipo quando lo crei. Qualsiasi pad esistente può essere trasformato in un modello spostandolo nella sezione <em>Modelli</em> del tuo CryptDrive. Puoi anche creare una copia di un pad da utilizzare come modello cliccando il pulsante template (<span class='fa fa-bookmark'></span>) nella barra degli strumenti dell'editor."
}
}
},
@ -630,10 +686,10 @@
"policy_whatweknow": "Cosa sappiamo di te",
"policy_title": "Informativa sulla privacy di CryptPad",
"policy_howweuse_p1": "Utilizziamo queste informazioni per migliorare le nostre decisioni in merito a come meglio pubblicizzare CryptPad, valutando quali dei nostri sforzi passati hanno avuto maggiore successo. Le informazioni sulla tua posizione ci permettono di sapere se dovremmo prendere in considerazione la possibilità di fornire un migliore supporto per lingue diverse dall'inglese.",
"policy_ads_p1": "Non mostriamo alcuna pubblicità online, anche se potremmo inserire collegamenti agli enti che finanziano la nostra ricerca.",
"policy_ads_p1": "Non mostriamo alcuna pubblicità online, anche se potremmo inserire link agli enti che finanziano la nostra ricerca.",
"policy_ads": "Pubblicità",
"policy_links_p1": "Questo sito contiene collegamenti ad altri siti, compresi quelli prodotti da altre organizzazioni. Non siamo responsabili delle pratiche relative alla privacy o dei contenuti di siti esterni. Come regola generale, i collegamenti a siti esterni vengono aperti in una nuova finestra del browser, per chiarire che si sta lasciando CryptPad.fr.",
"policy_links": "Collegamenti ad altri siti",
"policy_links_p1": "Questo sito contiene link ad altri siti, compresi quelli prodotti da altre organizzazioni. Non siamo responsabili delle pratiche relative alla privacy o dei contenuti di siti esterni. Come regola generale, i link a siti esterni vengono aperti in una nuova finestra del browser, per chiarire che si sta lasciando CryptPad.fr.",
"policy_links": "LInk ad altri siti",
"policy_whatwetell_p1": "Non forniamo a terzi le informazioni che raccogliamo o che ci fornite, a meno che non siamo legalmente obbligati a farlo.",
"policy_whatwetell": "Cosa comunichiamo a terzi riguardo a te",
"policy_howweuse_p2": "Le informazioni relative al tuo browser (sia che si tratti di un sistema operativo desktop che di uno mobile) ci aiutano a prendere decisioni quando si tratta di dare priorità ai miglioramenti delle funzionalità. Il nostro gruppo di sviluppo è piccolo e cerchiamo di fare scelte che migliorino l'esperienza del maggior numero di utenti possibile.",
@ -666,7 +722,7 @@
"mdToolbar_italic": "Corsivo",
"mdToolbar_bold": "Grassetto",
"mdToolbar_tutorial": "https://www.markdowntutorial.com/",
"mdToolbar_help": "Aiuto",
"mdToolbar_help": "Guida",
"pad_hideToolbar": "Nascondi barra degli strumenti",
"pad_showToolbar": "Mostra barra degli strumenti",
"download_step1": "Scaricamento in corso",
@ -700,54 +756,54 @@
"settings_creationSkipTrue": "Salta",
"settings_driveDuplicateLabel": "Nascondi i duplicati",
"settings_logoutEverywhereTitle": "Chiudi le sessioni remote",
"settings_logoutEverywhereButton": "Uscire",
"settings_logoutEverywhereButton": "Esci",
"settings_importDone": "Importazione completata",
"register_explanation": "<h3>Puntualizziamo un paio di cose:</h3><ul class='list-unstyled'><li><i class='fa fa-info-circle'> </i> La tua password è la chiave segreta di tutti i tuoi pad. Se la perdi non c'è alcun modo di recuperare i tuoi dati.</li><li><i class='fa fa-info-circle'> </i> Puoi importare i pad recenti di questo browser per averli nel tuo account.</li><li><i class='fa fa-info-circle'> </i> Se usi un computer condiviso, devi fare il log out quando hai finito, non è sufficiente chiudere il tab.</li></ul>",
"register_explanation": "<h3>Puntualizziamo un paio di cose:</h3><ul class='list-unstyled'><li><i class='fa fa-info-circle'> </i> La tua password è la chiave segreta di tutti i tuoi pad. Se la perdi non c'è alcun modo di recuperare i tuoi dati.</li><li><i class='fa fa-info-circle'> </i> Puoi importare i pad recenti di questo browser per averli nel tuo account.</li><li><i class='fa fa-info-circle'> </i> Se usi un computer condiviso, devi uscire quando hai finito, non è sufficiente chiudere la scheda.</li></ul>",
"features_f_subscribe_note": "Devi prima accedere a CryptPad",
"features_f_subscribe": "Abbonarsi a Premium",
"features_f_supporter_note": "Aiutarci a dimostrare che i software che proteggono la privacy devono essere la norma",
"features_f_supporter": "Diventare un supporter della privacy",
"features_f_supporter": "Diventa un supporter della privacy",
"features_f_support_note": "Supporto email professionale con il piano Team",
"features_f_storage2_note": "Da 5GB a 50GB in funzione del piano selezionato",
"features_f_storage2": "Spazio d'archivio supplementare",
"features_f_storage2": "Spazio d'archiviazione supplementare",
"features_f_reg_note": "Ed aiutare lo sviluppo di CryptPad",
"features_f_reg": "Tutte le funzioni degli utenti registrati",
"features_f_register_note": "Nessuna mail o informazione personale richieste",
"features_f_storage1_note": "I pads archiviati nel tuo CryptDrive non saranno mai eliminati per inattività",
"features_f_reg": "Tutte le funzionali degli utenti registrati",
"features_f_register_note": "Nessuna mail o informazione personale richiesta",
"features_f_storage1_note": "I pad conservati nel tuo CryptDrive non saranno mai eliminati per inattività",
"features_f_storage1": "Archivio permanente (50MB)",
"features_f_social_note": "Crea un profilo, usa un avatar, chatta con i contatti",
"features_f_devices_note": "Accesso a CryptDrive dovunque con il tuo account utente",
"features_f_devices": "I tuoi pads su tutti i tuoi apparecchi",
"features_f_cryptdrive1_note": "Dossier, dossier condivisi, modelli, tags",
"features_f_cryptdrive1": "Completa funzionalità di CryptDrive",
"features_f_devices_note": "Accesso al tuo CryptDrive dovunque con il tuo account utente",
"features_f_devices": "I tuoi pad su tutti i tuoi dispositivi",
"features_f_cryptdrive1_note": "Cartelle, cartelle condivise, modelli, tag",
"features_f_cryptdrive1": "Funzionalità complete di CryptDrive",
"features_f_anon_note": "Con migliore ergonomia e più controllo sui tuoi pads",
"features_f_anon": "Tutte le funzioni degli utenti anonimi",
"features_f_storage0_note": "I pads creati rischiano la cancellazione dopo 3 mesi di inattività",
"features_f_anon": "Tutte le funzionali degli utenti anonimi",
"features_f_storage0_note": "I pad creati rischiano la cancellazione dopo 3 mesi di inattività",
"features_f_storage0": "Tempo di conservazione limitato",
"features_f_cryptdrive0_note": "Conservazione nel browser dei pad visitati per ritrovarli più tardi",
"features_f_cryptdrive0": "Accesso limitato a CryptDrive",
"features_f_file0_note": "Guarda e scarica files condivisi da altri utenti",
"features_f_core_note": "Modifica, Importa & Esporta, Storia, Lista utenti, Chat",
"features_title": "Confronto delle funzioni",
"policy_choices_ads": "Se vuoi solamente bloccare la nostra piattaforma analitica puoi utilizzare uno strumento che blocca la pubblicità come <a href=\"https://www.eff.org/privacybadger\" title=\"download privacy badger\" target=\"_blank\" rel=\"noopener noreferrer\">Privacy Badger</a>.",
"policy_choices_vpn": "Se vuoi utilizzare la nostra istanza ma non vuoi esporre il tuo indirizzo IP puoi proteggerlo usando il <a href=\"https://www.torproject.org/projects/torbrowser.html.en\" title=\"downloads from the Tor project\" target=\"_blank\" rel=\"noopener noreferrer\">browser Tor</a>, oppure un <a href=\"https://riseup.net/en/vpn\" title=\"VPNs provided by Riseup\" target=\"_blank\" rel=\"noopener noreferrer\">VPN</a>.",
"policy_whatweknow_p2": "Utilizziamo <a href=\"https://www.elastic.co/products/kibana\" target=\"_blank\" rel=\"noopener noreferrer\" title=\"open source analytics platform\">Kibana</a>, una piattaforma analitica open source, per conoscere meglio i nostri utenti. Kibana ci dice come hai trovato CryptPad, entrando direttamente, attraverso un motore di ricerca, o provenendo da un altro sito web come Reddit o Twitter.",
"features_f_file0_note": "Guarda e scarica file condivisi da altri utenti",
"features_f_core_note": "Modifica, Importa & Esporta, Cronologia, Elenco utenti, Chat",
"features_title": "Confronto delle funzionali",
"policy_choices_ads": "Se vuoi solamente bloccare la nostra piattaforma di analisi puoi utilizzare uno strumento che blocca la pubblicità come <a href=\"https://www.eff.org/privacybadger\" title=\"download privacy badger\" target=\"_blank\" rel=\"noopener noreferrer\">Privacy Badger</a>.",
"policy_choices_vpn": "Se vuoi utilizzare la nostra istanza ma non vuoi esporre il tuo indirizzo IP puoi proteggerlo usando il <a href=\"https://www.torproject.org/projects/torbrowser.html.en\" title=\"downloads from the Tor project\" target=\"_blank\" rel=\"noopener noreferrer\">browser Tor</a>, oppure una <a href=\"https://riseup.net/en/vpn\" title=\"VPNs provided by Riseup\" target=\"_blank\" rel=\"noopener noreferrer\">VPN</a>.",
"policy_whatweknow_p2": "Utilizziamo <a href=\"https://www.elastic.co/products/kibana\" target=\"_blank\" rel=\"noopener noreferrer\" title=\"open source analytics platform\">Kibana</a>, una piattaforma di analisi open source, per conoscere meglio i nostri utenti. Kibana ci dice come hai trovato CryptPad, entrando direttamente, attraverso un motore di ricerca o provenendo da un altro sito web come Reddit o Twitter.",
"policy_whatweknow_p1": "Come applicazione ospitata sul web, CryptPad ha accesso a metadata esposti dal protocollo HTTP. Questo include il tuo indirizzo IP e altre intestazioni HTTP che possono essere usati per identificare il tuo browser. Puoi vedere quali informazioni condivide il tuo browser visitando<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending\" title=\"what http headers is my browser sending\">WhatIsMyBrowser.com</a>.",
"whatis_business_p2": "Si può installare CryptPad in sede e gli <a href=\"https://cryptpad.fr/about.html\">sviluppatori CryptPad </a> di XWiki SAS possono offrire supporto commerciale, personalizzazione e sviluppo. Contattaci su <a href=\"mailto:sales@cryptpad.fr\">sales@cryptpad.fr</a> per maggiori informazioni.",
"whatis_business_p1": "La crittografia Zero Knowledge di CryptPad moltiplica l'efficacia dei protocolli di sicurezza esistenti ricreandoli in maniera crittografica. Dato che i dati sensibili possono essere decrittati solo utilizzando le credenziali di accesso dell'utente, CryptPad è meno hackerabile dei servizi cloud tradizionali. Consulta il <a href='https://blog.cryptpad.fr/images/CryptPad-Whitepaper-v1.0.pdf'>CryptPad Whitepaper</a> per sapere come questo possa aiutare la tua impresa.",
"whatis_drive_p1": "Quando accedi a un pad in CryptPad il pad è automaticamente aggiunto al tuo CryptoDrive nel dossier principale. In seguito potrai organizzare questi pad in dossier o cestinarli. CryptPad ti permette di fare una ricerca tra i tuoi pad e organizzarli quando e come vuoi.",
"whatis_drive_p1": "Quando accedi a un pad in CryptPad il pad è automaticamente aggiunto al tuo CryptDrive nella cartella principale. In seguito potrai organizzare questi pad in cartelle o cestinarli. CryptPad ti permette di fare una ricerca tra i tuoi pad e di organizzarli quando e come vuoi.",
"whatis_zeroknowledge": "Zero Knowledge",
"whatis_zeroknowledge_p3": "Quando condividi il link di un documento, stai condividendo la chiave crittografica per accedere a quel documento, ma dato che la chiave è nel<a href=\"https://en.wikipedia.org/wiki/Fragment_identifier\">identificatore di frammenti</a>, non è mai inviata direttamente al server. Consulta il nostro <a href=\"https://blog.cryptpad.fr/2017/07/07/cryptpad-analytics-what-we-cant-know-what-we-must-know-what-we-want-to-know/\"> post nel bloig privacy</a> per capire a quali tipi di metadata abbiamo accesso ed a quali no.",
"features_f_core": "Funzioni comuni delle applicazioni",
"features_f_apps": "Accesso alle applicazioni principali",
"features_feature": "Funzione",
"features": "Funzioni",
"features_feature": "Funzionalità",
"features": "Funzionali",
"policy_choices": "Le tue scelte",
"whatis_drive": "Organizzazione con CryptDrive",
"whatis_zeroknowledge_p1": "Non vogliamo sapere cosa stai scrivendo e, grazie alla moderna crittografia, puoi essere certo che non possiamo farlo. CryptPad utilizza <strong>crittografia 100% lato client</strong>per proteggere il contenuto che stai scrivendo da noi, che ospitiamo il server.",
"whatis_collaboration_p3": "Puoi creare dei documenti di testo con <a href=\"http://ckeditor.com/\">CKEditor</a> così come documenti Markdown in tempo reale mentre scrivi. Puoi anche usare l'applicazione di sondaggio per pianificare eventi con più partecipanti.",
"whatis_collaboration_p2": "Puoi condividere l'accesso ad un documento CryptPad semplicemente condividendo il link. Puoi anche condividere un link che fornisce un accesso <em>di sola lettura</em> al pad, permettendoti di pubblicare i tuoi lavori collaborativi potendo ancora modificarli.",
"whatis_collaboration_p1": "Con CryptPad, puoi creare velocemente documenti collaborativi per prendere appunti e scrivere idee insieme. Quando ti registri e ti connetti ottieni la possibilità di importare files in un CryptDrive dove puoi organizzare tutti i tuoi pads. Come utente registrato hai 50 MB di spazio gratuito.",
"whatis_collaboration_p1": "Con CryptPad, puoi creare velocemente documenti collaborativi per prendere appunti e scrivere idee insieme. Quando ti registri e accedi ottieni la possibilità di caricare file in un CryptDrive dove puoi organizzare tutti i tuoi pad. Come utente registrato hai 50 MB di spazio gratuito.",
"whatis_collaboration": "Collaborazione veloce, facile",
"terms": "Condizioni",
"main_footerText": "Con CryptPad, puoi creare velocemente documenti collaborativi per prendere appunti e scrivere idee insieme.",
@ -771,55 +827,55 @@
"todo_title": "CryptTodo",
"download_step2": "Decodifica",
"download_button": "Decodifica & Scarica",
"upload_up": "Importa",
"upload_cancelled": "Cancellato",
"upload_tooLarge": "Questo file supera la dimensione massima di importazione autorizzata per il tuo account.",
"upload_up": "Carica",
"upload_cancelled": "Annullato",
"upload_tooLarge": "Questo file supera la dimensione massima di caricamento permessa per il tuo account.",
"upload_notEnoughSpace": "Non c'è spazio sufficiente per questo file nel tuo CryptDrive.",
"upload_success": "Il tuo file ({0}) è stato caricato con successo e aggiunto al tuo drive.",
"upload_serverError": "Errore del server: attualmente impossibile importare il file.",
"uploadFolder_modal_title": "Opzione di importazione del folder",
"upload_serverError": "Errore del server: impossibile caricare il file in questo momento.",
"uploadFolder_modal_title": "Opzione di caricamento cartelle",
"upload_modal_owner": "File posseduto",
"upload_modal_filename": "Nome del file (extension <em>{0}</em> aggiunta automaticamente)",
"settings_cursorShowHint": "Puoi decidere se vuoi vedere la posizione del tuo cursore degli altri utenti nei documenti collaborativi.",
"settings_cursorShowHint": "Puoi decidere se vuoi vedere la posizione del cursore degli altri utenti nei documenti collaborativi.",
"settings_cursorShareHint": "Puoi decidere se vuoi mostrare la posizione del tuo cursore agli altri utenti nei documenti collaborativi.",
"settings_cursorColorHint": "Cambiare il colore associato al tuo utente nei documenti collaborativi.",
"settings_cursorColorHint": "Cambia il colore associato al tuo utente nei documenti collaborativi.",
"settings_changePasswordPending": "La tua password è in fase di modifica. Non chiudere o ricaricare questa pagina fino al completamento del processo.",
"settings_changePasswordError": "Errore non previsto. Se non riesci ad accedere o cambiare la tua password contatta il tuo amministratore CryptPad.",
"settings_changePasswordConfirm": "Sei sicuro di voler cambiare la tua password? Dovrai riconnetterti su tutti i tuoi apparecchi.",
"settings_changePasswordHint": "Modifica la password del tuo account. Inserisci la tua password attuale e conferma la nuova password inserendola due volte.<br><b>Non possiamo reinstallare la tua password se la dimentichi, quindi sii molto prudente!</b>",
"settings_changePasswordError": "Si è verificato un errore imprevisto. Se non riesci ad accedere o cambiare la tua password contatta il tuo amministratore CryptPad.",
"settings_changePasswordConfirm": "Sei sicuro di voler cambiare la tua password? Dovrai accedere nuovamente su tutti i tuoi dispositivi.",
"settings_changePasswordHint": "Modifica la password del tuo account. Inserisci la tua password attuale e conferma la nuova password inserendola due volte.<br><b>Non possiamo reimpostare la tua password se la dimentichi, quindi sii molto prudente!</b>",
"settings_ownDrivePending": "Il tuo account è stato aggiornato. Non chiudere o ricaricare questa pagina prima che sia stato completato il processo.",
"settings_ownDriveConfirm": "Aggiornare il tuo account potrebbe richiedere tempo. Dovrai riconnetterti su tutti i tuoi apparecchi. Vuoi continuare?",
"settings_ownDriveConfirm": "Aggiornare il tuo account potrebbe richiedere tempo. Dovrai accedere nuovamente su tutti i tuoi dispositivi. Vuoi continuare?",
"settings_ownDriveHint": "Gli account più vecchi non hanno accesso alle ultime funzioni, per motivi tecnici. Un aggiornamento gratuito permetterà di attivare le funzioni attuali e preparare il tuo CryptDrive per futuri aggiornamenti.",
"settings_templateSkipHint": "Quando crei un nuovo pad vuoto, se hai dei modelli per questo tipo di pad, può apparire una finestra con la richiesta di utilizzare un modello. Qui puoi scegliere di non mostrare mai questa finestra e quindi di non utilizzare mai un modello.",
"settings_templateSkip": "Saltare la schermata di scelta di un modello",
"settings_creationSkipFalse": "Mostrare",
"settings_creationSkipHint": "La schermata di creazione di pad offre nuove opzioni per creare un pad, fornendo maggior controllo e sicurezza per i tuoi dati. Tuttavia potrebbe rallentare il lavoro aggiungendo un passaggio supplementare quindi, qui, hai la possibilità di scegliere di saltare la schermata e utilizzare i parametri di default selezionati sopra.",
"settings_creationSkip": "Salta la schermata di creazione di pad",
"settings_templateSkip": "Salta la schermata di scelta di un modello",
"settings_creationSkipFalse": "Mostra",
"settings_creationSkipHint": "La schermata di creazione del pad offre nuove opzioni per creare un pad, fornendo maggior controllo e sicurezza per i tuoi dati. Tuttavia potrebbe rallentare il lavoro aggiungendo un passaggio supplementare quindi, qui, hai la possibilità di scegliere di saltare la schermata e utilizzare i parametri predefiniti selezionati sopra.",
"settings_creationSkip": "Salta la schermata di creazione del pad",
"settings_padSpellcheckLabel": "Attiva la verifica ortografica",
"settings_padSpellcheckHint": "Questa opzione permette di attivare la verifica ortografica nell'editor di testo. Gli errori saranno sottolineati in rosso e le correzioni saranno disponibili cliccando a destra sul mouse e premendo il tasto Ctrl o Meta.",
"settings_padSpellcheckTitle": "Verifica ortografica",
"settings_padSpellcheckHint": "Questa opzione permette di attivare il controllo ortografico nell'editor di testo. Gli errori saranno sottolineati in rosso e le correzioni saranno disponibili cliccando con il tasto destro del mouse e premendo il tasto Ctrl o Meta.",
"settings_padSpellcheckTitle": "Controllo ortografico",
"settings_padWidthLabel": "Ridurre la larghezza dell'editor",
"settings_padWidthHint": "I pad di testo occupano di default la massima larghezza disponibile sullo schermo e la lettura può essere difficile. Potete ridurre la larghezza dell'editor qui.",
"settings_padWidth": "Massima larghezza dell'editor",
"settings_codeUseTabs": "Rientrare usando tabs (invece di spazi)",
"settings_codeUseTabs": "Indentare usando le tabulazioni (al posto degli spazi)",
"settings_driveDuplicateTitle": "Duplicati dei pad di cui sei proprietario",
"settings_logoutEverywhereConfirm": "Sei sicuro? Dovrai riconnetterti su tutti i tuoi apparecchi.",
"settings_logoutEverywhere": "Forzare l'uscita da tutte le altre sessioni web",
"settings_logoutEverywhereConfirm": "Sei sicuro? Dovrai accedere su tutti i tuoi dispositivi.",
"settings_logoutEverywhere": "Forza l'uscita da tutte le altre sessioni web",
"settings_usageAmount": "I tuoi pads appuntati occupano {0}MB",
"settings_pinningError": "Qualcosa è andato storto",
"settings_pinningNotAvailable": "I pads appuntati sono disponibili solo per gli utenti registrati.",
"settings_usageTitle": "Guarda la quantità totale dei tuoi pads appuntati in MB",
"settings_usage": "Utilizzo",
"settings_publicSigningKey": "Firma digitale pubblica",
"settings_anonymous": "Non sei collegato. La configurazione è specifica per questo browser.",
"settings_deleted": "Il tuo user account è stato cancellato. Premi OK per tornare alla home page.",
"settings_anonymous": "Non sei connesso. Queste impostazioni sono specifiche per questo browser.",
"settings_deleted": "Il tuo account utente è stato cancellato. Premi OK per tornare alla home page.",
"settings_deleteModal": "Condividi le seguenti informazioni con il tuo amministratore CryptPad per rimuovere i tuoi dati dal server.",
"settings_deleteConfirm": "Cliccando OK cancellerai il tuo account. Vuoi continuare?",
"settings_deleteConfirm": "Cliccando OK cancellerai il tuo account definitivamente. Sei sicuro?",
"settings_autostoreHint": "<b>Automatico</b> Tutti i pad che visiti sono conservati nel tuo CryptDrive.<br><b>Manuale (chiedi sempre)</b> Se non hai ancora conservato alcun pad ti verrà chiesto se vuoi conservarli nel tuo CryptDrive.<br><b>Manuale (non chiedere mai)</b> I Pads non sono conservati automaticamente nel tuo Cryptpad. L'opzione di conservarli sarà nascosta.",
"settings_autostoreNo": "Manuale (non chiedere mai)",
"settings_autostoreYes": "Automatico",
"settings_autostoreTitle": "Conservazione pad nel CryptDrive",
"settings_importTitle": "Importare i pad recenti di questo browser nel tuo CryptDrive",
"settings_importTitle": "Importa i pad recenti di questo browser nel tuo CryptDrive",
"kanban_noTags": "Nessun tag",
"kanban_tags": "Filtra per tag",
"kanban_delete": "Elimina",
@ -949,5 +1005,99 @@
"sharedFolders_create_name": "Nome della cartella",
"share_contactCategory": "Contatti",
"share_linkCopy": "Copia",
"share_linkOpen": "Anteprima"
"share_linkOpen": "Anteprima",
"header_homeTitle": "Vai alla homepage di CryptPad",
"header_logoTitle": "Vai al tuo CryptDrive",
"updated_0_header_logoTitle": "Vai al tuo CryptDrive",
"four04_pageNotFound": "Non riusciamo a trovare la pagina che stai cercando.",
"tos_3rdparties": "Non forniamo dati individuali a terze parti a meno che non sia richiesto dalla legge.",
"tos_logs": "I metadati forniti dal tuo browser al server possono essere registrati allo scopo di mantenere il servizio.",
"tos_e2ee": "I contenuti di CryptPad possono essere letti e modificati scopra od ottenga in qualsiasi modo la porzione di pad che funge da identificativo. Raccomandiamo di usare una messaggistica con crittografia end-to-end (e2ee) per condividere link, e non ci assumiamo nessuna responsabilità nel caso in cui questo link sia diffuso.",
"tos_availability": "Speriamo che tu trovi utile questo servizio, ma la disponibilità e le performance non possono essere garantite. Esporta con regolarità i tuoi dati.",
"tos_legal": "Per favore non essere dannoso, improprio, o fare qualsiasi cosa illegale.",
"tos_title": "Termini di servizio di CryptPad",
"support_close": "Chiudi il ticket",
"profile_login": "Devi accedere per aggiungere questo utente ai tuoi contatti",
"creation_404": "Questo pad non esiste più. Usa il modulo seguente per creare un nuovo pad.",
"historyTrim_historySize": "Cronologia: {0}",
"trimHistory_button": "Elimina cronologia",
"trimHistory_success": "La cronologia è stata eliminata",
"trimHistory_needMigration": "<a>Aggiorna il tuo CryptDrive</a> per abilitare questa funzionalità.",
"trimHistory_currentSize": "Dimensione attuale della cronologia: <b>{0}</b>",
"settings_trimHistoryTitle": "Elimina cronologia",
"profile_copyKey": "Copia la chiave pubblica",
"admin_openFilesTitle": "Apri i file",
"canvas_select": "Seleziona",
"logoutEverywhere": "Esci ovunque",
"driveReadmeTitle": "Cos'è CryptPad?",
"readme_welcome": "Benvenuto in CryptPad!",
"edit": "modifica",
"readme_cat2_l2": "Modifica il titolo del pad cliccando sulla matita",
"readme_cat3": "Scopri le app di CryptPad",
"tips": {
"tags": "Tagga i tuoi pad e inizia una ricerca con # nel tuo CryptDrive per trovarli",
"shortcuts": "`ctrl+b`, `ctrl+i` e `ctrl+u`sono le scorciatoie per grassetto, corsivo e sottolineato.",
"indent": "Negli elenchi numerati e puntati puoi usare tab o shift+tab per aumentare o diminuire velocemente l'indentazione.",
"filenames": "Puoi rinominare i file nel tuo CryptDrive, questo nome è solo per te.",
"profile": "Gli utenti registrati possono creare un profilo dal menu utente in alto a destra.",
"avatars": "Puoi caricare un avatar nel tuo profilo. Le persone lo vedranno quando collabori in un pad."
},
"creation_passwordValue": "Password",
"creation_propertiesTitle": "Disponibilità",
"password_submit": "Invia",
"password_show": "Mostra",
"properties_changePassword": "Modifica la password",
"share_linkCategory": "Link",
"share_linkEdit": "Modifica",
"share_linkView": "Visualizza",
"contact_devHint": "Per la richiesta di funzionalità, miglioramenti all'usabilità o per dire grazie.",
"admin_diskUsageTitle": "Utilizzo del disco",
"friendRequest_received": "<b>{0}</b> vorrebbe diventare un tuo contatto",
"share_linkFriends": "Condividi con i contatti",
"admin_cat_support": "Supporto",
"support_cat_new": "Nuovo ticket",
"support_formTitle": "Titolo del ticket",
"support_cat_tickets": "Ticket esistenti",
"support_listTitle": "Ticket di supporto",
"support_showData": "Mostra/nascondi i dati dell'utente",
"notifications_cat_friends": "Richieste di contatto",
"notifications_dismissAll": "Ignora tutte",
"team_cat_create": "Nuovo",
"team_cat_back": "Torna ai team",
"owner_addTeamText": "...o un team",
"contacts_unmute": "Suona",
"contacts_mutedUsers": "Account silenziati",
"creation_noOwner": "Nessun proprietario",
"creation_appMenuName": "Modalità avanzata (Ctrl + E)",
"password_placeholder": "Scrivi qui la password...",
"properties_addPassword": "Aggiungi una password",
"properties_passwordSame": "La nuova password deve essere diversa da quella attuale.",
"properties_passwordError": "Si è verificato un errore nel tentativo di modificare la password. Riprova.",
"properties_changePasswordButton": "Invia",
"share_linkAccess": "Diritti d'accesso",
"sharedFolders_create": "Crea una cartella condivisa",
"settings_codeSpellcheckTitle": "Controllo ortografico",
"drive_activeOld": "Pad meno recenti",
"supportPage": "Supporto",
"admin_supportAddKey": "Aggiungi chiave privata",
"support_formHint": "Questo modulo può essere usato per creare un nuovo ticket per il supporto. Usalo per contattare gli amministratori per risolvere problemi o fare domande in modo sicuro. Non creare un nuovo ticket se hai già un ticket aperto per lo stesso problema ma usa il pulsante rispondi per fornire maggiori informazioni.",
"support_remove": "Rimuovi il ticket",
"support_closed": "Il ticket è stato chiuso",
"notifications_cat_archived": "Cronologia",
"support_notification": "Un amministratore ha risposto al tuo ticket per il supporto",
"team_listLoad": "Apri",
"passwordFaqLink": "Leggi di più sulle password",
"contacts_mute": "Silenzia",
"contacts_manageMuted": "Gestisci silenziati",
"contacts_muteInfo": "Non riceverai alcuna notifica o messaggio dagli utenti silenziati.<br>Loro non sapranno di essere stati silenziati. ",
"team_inviteEnterPassword": "Inserisci la password dell'invito per continuare.",
"burnAfterReading_generateLink": "Clicca sul pulsante sottostante per generare un link.",
"burnAfterReading_proceed": "visualizza ed elimina",
"oo_sheetMigration_complete": "Versione aggiornata disponibile, premi OK per ricaricare.",
"readme_cat2": "Realizza pad come un professionista",
"view": "visualizza",
"timeoutError": "Un errore ha interrotto la tua connessione al server. <br>Premi <em>Esc</em> per ricaricare la pagina.",
"support_disabledTitle": "Il supporto non è abilitato",
"support_listHint": "Qui c'è l'elenco dei ticket inviati agli amministratori e delle loro risposte. Un ticket chiuso non può essere riaperto ma puoi farne uno nuovo. Puoi nascondere i ticket che sono stati chiusi.",
"creation_ownedTitle": "Tipo di pad"
}

View File

@ -174,5 +174,41 @@
"button_newwhiteboard": "Ny whiteboard",
"button_newslide": "Ny presentation",
"button_newpoll": "Ny votering",
"button_newpad": "Nytt textdokument"
"button_newpad": "Nytt textdokument",
"kanban_deleteBoard": "Är du säker på att du vill ta bort denna vägg?",
"kanban_working": "Pågående",
"kanban_done": "Färdigt",
"kanban_todo": "Att göra",
"kanban_item": "Artikel {0}",
"kanban_newBoard": "Ny vägg",
"pad_mediatagOptions": "Bildegenskaper",
"pad_mediatagImport": "Spara i din CryptDrive",
"pad_mediatagPreview": "Förhandsvisning",
"pad_mediatagBorder": "Rambredd (px)",
"pad_mediatagRatio": "Behåll förhållande",
"pad_mediatagHeight": "Höjd (px)",
"pad_mediatagWidth": "Bredd (px)",
"pad_mediatagTitle": "Inställningar för Media Tag",
"openLinkInNewTab": "Öppna länk i ny flik",
"history_version": "Version:",
"history_restoreDone": "Dokument återställt",
"history_restorePrompt": "Är du säker på att du ville ersätta den valda versionen av dokumentet med den visade?",
"history_restoreTitle": "Återskapa den valda versionen av dokumentet",
"history_closeTitle": "Stäng historiken",
"history_loadMore": "Ladda mer historik",
"history_prev": "Äldre version",
"history_next": "Nyare version",
"historyButton": "Visa dokumenthistoriken",
"historyText": "Historik",
"help_button": "Hjälp",
"hide_help_button": "Dölj hjälp",
"show_help_button": "Visa hjälp",
"cancelButton": "Avbryt (Esc)",
"cancel": "Avbryt",
"okButton": "OK (Enter)",
"ok": "OK",
"notifyLeft": "{0} har lämnat sammarbetssessionen",
"notifyRenamed": "{0} är nu känd som {1}",
"notifyJoined": "{0} har gått med i sammarbetssessionen",
"fileEmbedTag": "Placera sedan denna Media Tag där du vill bädda in den på din sida:"
}