diff --git a/CHANGELOG.md b/CHANGELOG.md index d2cabd99..ec377db6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +# 1.2.7 + * NEW: Visit a specific revision in the timeslider by suffixing #%revNumber% IE http://localhost/p/test/timeslider#12 + * NEW: Link to plugin on Admin page allows admins to easily see plugin details in a new window by clicking on the plugin name + * NEW: Automatically see plugins that require update and be able to one click update + * NEW: API endpoints for Chat .. getChatHistory, getChatHead + * NEW: API endpoint to see a pad diff in HTML format from revision x to revision y .. createPadDiffHTML + * NEW: Real time plugin search & unified menu UI for admin pages + * Fix: make docs + * Fix: Timeslider UI bug with slider not being in position + * Fix: IE8 language issue where it wouldn't load pads due to IE8 suckling on the bussum of hatrid + * Fix: Import timeout issue + * Fix: Import now works if Params are set in pad URL + * Fix: Convert script + * Other: Various new language strings + * Other: Clean up the getParams functionality + * Other: Various new EEJS blocks: index, timeslider, html etc. + # 1.2.6 * Fix: Package file UeberDB reference * New #users EEJS block for plugins diff --git a/Makefile b/Makefile index 4e870a45..b656d5d9 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ outdoc_files = $(addprefix out/,$(doc_sources:.md=.html)) docassets = $(addprefix out/,$(wildcard doc/assets/*)) VERSION = $(shell node -e "console.log( require('./src/package.json').version )") +UNAME := $(shell uname -s) docs: $(outdoc_files) $(docassets) @@ -14,7 +15,11 @@ out/doc/assets/%: doc/assets/% out/doc/%.html: doc/%.md mkdir -p $(@D) node tools/doc/generate.js --format=html --template=doc/template.html $< > $@ - cat $@ | sed 's/__VERSION__/${VERSION}/' > $@ +ifeq ($(UNAME),Darwin) + sed -i '' 's/__VERSION__/${VERSION}/' $@ +else + sed -i 's/__VERSION__/${VERSION}/' $@ +endif clean: rm -rf out/ diff --git a/bin/convert.js b/bin/convert.js index 4bbdd667..a2f3bdd4 100644 --- a/bin/convert.js +++ b/bin/convert.js @@ -1,4 +1,3 @@ - var startTime = new Date().getTime(); var fs = require("fs"); var ueberDB = require("../src/node_modules/ueberDB"); @@ -403,7 +402,7 @@ function convertPad(padId, callback) } catch(e) { - console.error("Error while converting pad " + padId + ", pad skiped"); + console.error("Error while converting pad " + padId + ", pad skipped"); console.error(e.stack ? e.stack : JSON.stringify(e)); callback(); return; diff --git a/doc/api/http_api.md b/doc/api/http_api.md index 0d2cc375..0543ef71 100644 --- a/doc/api/http_api.md +++ b/doc/api/http_api.md @@ -292,6 +292,34 @@ returns the text of a pad formatted as HTML * `{code: 0, message:"ok", data: {html:"Welcome Text
More Text"}}` * `{code: 1, message:"padID does not exist", data: null}` +### Chat +#### getChatHistory(padID, [start, end]) + * API >= 1.2.7 + +returns + +* a part of the chat history, when `start` and `end` are given +* the whole chat histroy, when no extra parameters are given + + +*Example returns:* + +* `{"code":0,"message":"ok","data":{"messages":[{"text":"foo","userId":"a.foo","time":1359199533759,"userName":"test"},{"text":"bar","userId":"a.foo","time":1359199534622,"userName":"test"}]}}` +* `{code: 1, message:"start is higher or equal to the current chatHead", data: null}` +* `{code: 1, message:"padID does not exist", data: null}` + +#### getChatHead(padID) + * API >= 1.2.7 + +returns the chatHead (last number of the last chat-message) of the pad + + +*Example returns:* + +* `{code: 0, message:"ok", data: {chatHead: 42}}` +* `{code: 1, message:"padID does not exist", data: null}` + + ### Pad Group pads are normal pads, but with the name schema GROUPID$PADNAME. A security manager controls access of them and its forbidden for normal pads to include a $ in the name. @@ -327,7 +355,7 @@ returns the number of user that are currently editing this pad returns the list of users that are currently editing this pad *Example returns:* - * `{code: 0, message:"ok", data: {padUsers: [{colorId:"#c1a9d9","name":"username1","timestamp":1345228793126},{"colorId":"#d9a9cd","name":"Hmmm","timestamp":1345228796042}]}}` + * `{code: 0, message:"ok", data: {padUsers: [{colorId:"#c1a9d9","name":"username1","timestamp":1345228793126,"id":"a.n4gEeMLsvg12452n"},{"colorId":"#d9a9cd","name":"Hmmm","timestamp":1345228796042,"id":"a.n4gEeMLsvg12452n"}]}}` * `{code: 0, message:"ok", data: {padUsers: []}}` #### deletePad(padID) diff --git a/settings.json.template b/settings.json.template index 04c09751..4b18d780 100644 --- a/settings.json.template +++ b/settings.json.template @@ -101,5 +101,5 @@ "loglevel": "INFO", // restrict socket.io transport methods - "socketTransportProtocols" : ['xhr-polling', 'jsonp-polling', 'htmlfile'] + "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"] } diff --git a/src/locales/ast.json b/src/locales/ast.json index 1437d869..7beb706a 100644 --- a/src/locales/ast.json +++ b/src/locales/ast.json @@ -78,6 +78,7 @@ "pad.share.emebdcode": "Incrustar URL", "pad.chat": "Chat", "pad.chat.title": "Abrir el chat d'esti bloc.", + "pad.chat.loadmessages": "Cargar m\u00e1s mensaxes", "timeslider.pageTitle": "Eslizador de tiempu de {{appTitle}}", "timeslider.toolbar.returnbutton": "Tornar al bloc", "timeslider.toolbar.authors": "Autores:", @@ -99,6 +100,8 @@ "timeslider.month.october": "d'ochobre", "timeslider.month.november": "de payares", "timeslider.month.december": "d'avientu", + "timeslider.unnamedauthor": "{{num}} autor an\u00f3nimu", + "timeslider.unnamedauthors": "{{num}} autores an\u00f3nimos", "pad.savedrevs.marked": "Esta revisi\u00f3n marcose como revisi\u00f3n guardada", "pad.userlist.entername": "Escribi'l to nome", "pad.userlist.unnamed": "ensin nome", diff --git a/src/locales/az.json b/src/locales/az.json index 1e6439fd..95c65798 100644 --- a/src/locales/az.json +++ b/src/locales/az.json @@ -50,17 +50,21 @@ "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (A\u00e7\u0131q S\u0259n\u0259d Format\u0131)", "pad.importExport.exportdokuwiki": "DokuWiki", + "pad.importExport.abiword.innerHTML": "Siz yaln\u0131z adi m\u0259tnd\u0259n v\u0259 ya HTML-d\u0259n idxal ed\u0259 bil\u0259rsiniz. \u0130dxal\u0131n daha m\u00fcr\u0259kk\u0259b funksiyalar\u0131 \u00fc\u00e7\u00fcn, z\u0259hm\u0259t olmasa, AbiWord-i qura\u015fd\u0131r\u0131n<\/a>.", "pad.modals.connected": "Ba\u011fland\u0131.", "pad.modals.reconnecting": "Sizin pad yenid\u0259n qo\u015fulur..", "pad.modals.forcereconnect": "M\u0259cbur t\u0259krar\u0259n ba\u011flan", "pad.modals.userdup": "Ba\u015fqa p\u0259nc\u0259r\u0259d\u0259 art\u0131q a\u00e7\u0131qd\u0131r", + "pad.modals.userdup.explanation": "S\u0259n\u0259d, ola bilsin ki, bu kompyuterd\u0259, brauzerin bir ne\u00e7\u0259 p\u0259nc\u0259r\u0259sind\u0259 a\u00e7\u0131lm\u0131\u015fd\u0131r.", "pad.modals.userdup.advice": "Bu p\u0259nc\u0259r\u0259d\u0259n istifad\u0259yl\u0259 yenid\u0259n qo\u015fulun.", "pad.modals.unauth": "\u0130caz\u0259li deyil", "pad.modals.unauth.explanation": "Bu s\u0259hif\u0259y\u0259 baxd\u0131\u011f\u0131n\u0131z vaxt sizin icaz\u0259niz d\u0259yi\u015filib. B\u0259rpa etm\u0259k \u00fc\u015f\u00fcn yenid\u0259n c\u0259hd edin.", "pad.modals.looping": "\u018flaq\u0259 k\u0259sildi.", "pad.modals.looping.explanation": "Sinxronla\u015fd\u0131rma serveri il\u0259 kommunikasiya x\u0259tas\u0131 var.", + "pad.modals.looping.cause": "Ola bilsin ki, siz uy\u011fun olmayan fayrvol v\u0259 ya proksi vasit\u0259si il\u0259 qo\u015fulma\u011fa c\u0259hd g\u00f6st\u0259rirsiniz.", "pad.modals.initsocketfail": "Server \u0259l\u00e7atmazd\u0131r.", "pad.modals.initsocketfail.explanation": "Sinxronla\u015fd\u0131rma serverin\u0259 qo\u015fulma m\u00fcmk\u00fcns\u00fczd\u00fcr.", + "pad.modals.initsocketfail.cause": "Ehtimal ki, bu problem sizin brauzerinizl\u0259 v\u0259 ya internet-birl\u0259\u015fm\u0259nizl\u0259 \u0259laq\u0259d\u0259rdir.", "pad.modals.slowcommit": "\u018flaq\u0259 k\u0259sildi.", "pad.modals.slowcommit.explanation": "Server cavab vermir.", "pad.modals.slowcommit.cause": "Bu \u015f\u0259b\u0259k\u0259 ba\u011flant\u0131s\u0131nda probleml\u0259r yarana bil\u0259r.", @@ -75,6 +79,7 @@ "pad.share.emebdcode": "URL-ni yay\u0131mla", "pad.chat": "S\u00f6hb\u0259t", "pad.chat.title": "Bu pad \u00fc\u00e7\u00fcn chat a\u00e7\u0131n.", + "pad.chat.loadmessages": "Daha \u00e7ox mesaj y\u00fckl\u0259", "timeslider.pageTitle": "{{appTitle}} Vaxt c\u0259dv\u0259li", "timeslider.toolbar.returnbutton": "Pad-a qay\u0131t", "timeslider.toolbar.authors": "M\u00fc\u0259llifl\u0259r:", @@ -96,6 +101,9 @@ "timeslider.month.october": "Oktyabr", "timeslider.month.november": "Noyabr", "timeslider.month.december": "Dekabr", + "timeslider.unnamedauthor": "{{num}} ads\u0131z m\u00fc\u0259llif", + "timeslider.unnamedauthors": "{{num}} ads\u0131z m\u00fc\u0259llifl\u0259r", + "pad.savedrevs.marked": "Bu versiya indi yadda\u015fa saxlanm\u0131\u015f kimi ni\u015fanland\u0131", "pad.userlist.entername": "Ad\u0131n\u0131z\u0131 daxil et", "pad.userlist.unnamed": "ads\u0131z", "pad.userlist.guest": "Qonaq", @@ -104,8 +112,10 @@ "pad.editbar.clearcolors": "B\u00fct\u00fcn s\u0259n\u0259dl\u0259rd\u0259 m\u00fc\u0259lliflik r\u0259ngl\u0259rini t\u0259mizl\u0259?", "pad.impexp.importbutton": "\u0130ndi idxal edin", "pad.impexp.importing": "\u0130dxal...", + "pad.impexp.confirmimport": "Fayl\u0131n idxal\u0131 cari m\u0259tni yenil\u0259y\u0259c\u0259k. Siz \u0259minsinizmi ki, davam etm\u0259k ist\u0259yirsiniz?", "pad.impexp.convertFailed": "Biz bu fayl idxal etm\u0259k m\u00fcmk\u00fcn deyil idi. Xahi\u015f olunur m\u00fcxt\u0259lif s\u0259n\u0259dd\u0259n istifad\u0259 edin v\u0259 ya kopyalay\u0131b yap\u0131\u015fd\u0131rmaq yolundan istifad\u0259 edin", "pad.impexp.uploadFailed": "Y\u00fckl\u0259m\u0259d\u0259 s\u0259hv, xahi\u015f olunur yen\u0259 c\u0259hd edin", "pad.impexp.importfailed": "\u0130dxal zaman\u0131 s\u0259hv", - "pad.impexp.copypaste": "Xahi\u015f edirik kopyalay\u0131b yap\u0131\u015fd\u0131r\u0131n" + "pad.impexp.copypaste": "Xahi\u015f edirik kopyalay\u0131b yap\u0131\u015fd\u0131r\u0131n", + "pad.impexp.exportdisabled": "{{ type}} format\u0131nda ixrac s\u00f6nd\u00fcr\u00fclm\u00fc\u015fd\u00fcr. \u018ftrafl\u0131 informasiya \u00fc\u00e7\u00fcn sistem administratoruna m\u00fcraci\u0259t ediniz." } \ No newline at end of file diff --git a/src/locales/ca.json b/src/locales/ca.json index 3eb84020..ca4d3f19 100644 --- a/src/locales/ca.json +++ b/src/locales/ca.json @@ -8,31 +8,49 @@ }, "pad.toolbar.bold.title": "Negreta (Ctrl-B)", "pad.toolbar.italic.title": "Cursiva (Ctrl-I)", + "pad.toolbar.underline.title": "Subratllat (Ctrl-U)", + "pad.toolbar.strikethrough.title": "Ratllat", "pad.toolbar.ol.title": "Llista ordenada", "pad.toolbar.ul.title": "Llista sense ordenar", + "pad.toolbar.indent.title": "Sagnat", + "pad.toolbar.unindent.title": "Sagnat invers", "pad.toolbar.undo.title": "Desf\u00e9s (Ctrl-Z)", "pad.toolbar.redo.title": "Ref\u00e9s (Ctrl-Y)", + "pad.toolbar.clearAuthorship.title": "Neteja els colors d'autoria", + "pad.toolbar.savedRevision.title": "Revisions desades", "pad.toolbar.settings.title": "Configuraci\u00f3", + "pad.toolbar.showusers.title": "Mostra els usuaris d\u2019aquest pad", "pad.colorpicker.save": "Desa", "pad.colorpicker.cancel": "Cancel\u00b7la", "pad.loading": "S'est\u00e0 carregant...", + "pad.wrongPassword": "La contrasenya \u00e9s incorrecta", + "pad.settings.myView": "La meva vista", "pad.settings.linenocheck": "N\u00fameros de l\u00ednia", "pad.settings.fontType": "Tipus de lletra:", "pad.settings.fontType.normal": "Normal", + "pad.settings.globalView": "Vista global", "pad.settings.language": "Llengua:", "pad.importExport.import_export": "Importaci\u00f3\/exportaci\u00f3", + "pad.importExport.import": "Puja qualsevol fitxer de text o document", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "Text net", + "pad.modals.connected": "Connectat.", + "pad.modals.forcereconnect": "For\u00e7a tornar a connectar", + "pad.modals.unauth": "No autoritzat", "pad.modals.looping": "Desconnectat.", + "pad.modals.initsocketfail": "El servidor no \u00e9s accessible.", + "pad.modals.initsocketfail.explanation": "No s'ha pogut connectar amb el servidor de sincronitzaci\u00f3.", "pad.modals.slowcommit": "Desconnectat.", "pad.modals.slowcommit.explanation": "El servidor no respon.", "pad.modals.deleted": "Suprimit.", + "pad.modals.disconnected": "Heu estat desconnectat.", "pad.share.readonly": "Nom\u00e9s de lectura", "pad.share.link": "Enlla\u00e7", "pad.chat": "Xat", "timeslider.toolbar.authors": "Autors:", "timeslider.toolbar.authorsList": "No hi ha autors", "timeslider.toolbar.exportlink.title": "Exporta", + "timeslider.exportCurrent": "Exporta la versi\u00f3 actual com a:", "timeslider.version": "Versi\u00f3 {{version}}", "timeslider.month.january": "Gener", "timeslider.month.february": "Febrer", diff --git a/src/locales/da.json b/src/locales/da.json index 3e785b58..dc6c0f25 100644 --- a/src/locales/da.json +++ b/src/locales/da.json @@ -78,6 +78,7 @@ "pad.share.emebdcode": "Integrerings URL", "pad.chat": "Chat", "pad.chat.title": "\u00c5ben chat for denne pad.", + "pad.chat.loadmessages": "Indl\u00e6s flere meddelelser", "timeslider.pageTitle": "{{appTitle}} Timeslider", "timeslider.toolbar.returnbutton": "Tilbage til pad", "timeslider.toolbar.authors": "Forfattere:", diff --git a/src/locales/de.json b/src/locales/de.json index 1bdbdaf3..7c51fa91 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -103,6 +103,8 @@ "timeslider.month.october": "Oktober", "timeslider.month.november": "November", "timeslider.month.december": "Dezember", + "timeslider.unnamedauthor": "{{num}} unbenannter Autor", + "timeslider.unnamedauthors": "{{num}} unbenannte Autoren", "pad.savedrevs.marked": "Diese Version wurde jetzt als gespeicherte Version gekennzeichnet", "pad.userlist.entername": "Geben Sie Ihren Namen ein", "pad.userlist.unnamed": "unbenannt", diff --git a/src/locales/el.json b/src/locales/el.json index dced1d4f..33cb6c21 100644 --- a/src/locales/el.json +++ b/src/locales/el.json @@ -8,23 +8,23 @@ ] }, "index.newPad": "\u039d\u03ad\u03bf Pad", - "index.createOpenPad": "\u03ae \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1\/\u03ac\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1 \u03b5\u03bd\u03cc\u03c2 Pad \u03bc\u03b5 \u03c4\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1:", + "index.createOpenPad": "\u03ae \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1\/\u03ac\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1 \u03b5\u03bd\u03cc\u03c2 Pad \u03bc\u03b5 \u03cc\u03bd\u03bf\u03bc\u03b1:", "pad.toolbar.bold.title": "\u0388\u03bd\u03c4\u03bf\u03bd\u03b1 (Ctrl-B)", "pad.toolbar.italic.title": "\u03a0\u03bb\u03ac\u03b3\u03b9\u03b1 (Ctrl-I)", "pad.toolbar.underline.title": "\u03a5\u03c0\u03bf\u03b3\u03c1\u03ac\u03bc\u03bc\u03b9\u03c3\u03b7 (Ctrl-U)", "pad.toolbar.strikethrough.title": "\u0394\u03b9\u03b1\u03ba\u03c1\u03b9\u03c4\u03ae \u03b4\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae", "pad.toolbar.ol.title": "\u03a4\u03b1\u03be\u03b9\u03bd\u03bf\u03bc\u03b7\u03bc\u03ad\u03bd\u03b7 \u03bb\u03af\u03c3\u03c4\u03b1", "pad.toolbar.ul.title": "\u039b\u03af\u03c3\u03c4\u03b1 \u03c7\u03c9\u03c1\u03af\u03c2 \u03c3\u03b5\u03b9\u03c1\u03ac", - "pad.toolbar.indent.title": "\u0395\u03c3\u03bf\u03c7\u03ae", - "pad.toolbar.unindent.title": "\u0395\u03c3\u03bf\u03c7\u03ae", + "pad.toolbar.indent.title": "\u0395\u03b9\u03c3\u03b1\u03b3\u03c9\u03b3\u03ae \u03b5\u03c3\u03bf\u03c7\u03ae\u03c2", + "pad.toolbar.unindent.title": "\u0391\u03c6\u03b1\u03af\u03c1\u03b5\u03c3\u03b7 \u03b5\u03c3\u03bf\u03c7\u03ae\u03c2", "pad.toolbar.undo.title": "\u0391\u03bd\u03b1\u03af\u03c1\u03b5\u03c3\u03b7 (Ctrl-Z)", "pad.toolbar.redo.title": "\u0395\u03c0\u03b1\u03bd\u03ac\u03bb\u03b7\u03c8\u03b7 (Ctrl-Y)", "pad.toolbar.clearAuthorship.title": "\u039a\u03b1\u03b8\u03b1\u03c1\u03b9\u03c3\u03bc\u03cc\u03c2 \u03a7\u03c1\u03c9\u03bc\u03ac\u03c4\u03c9\u03bd \u03a3\u03c5\u03bd\u03c4\u03b1\u03ba\u03c4\u03ce\u03bd", "pad.toolbar.import_export.title": "\u0395\u03b9\u03c3\u03b1\u03b3\u03c9\u03b3\u03ae\/\u0395\u03be\u03b1\u03b3\u03c9\u03b3\u03ae \u03b1\u03c0\u03cc\/\u03c3\u03b5 \u03b4\u03b9\u03b1\u03c6\u03bf\u03c1\u03b5\u03c4\u03b9\u03ba\u03bf\u03cd\u03c2 \u03c4\u03cd\u03c0\u03bf\u03c5\u03c2 \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd", "pad.toolbar.timeslider.title": "\u03a7\u03c1\u03bf\u03bd\u03bf\u03b4\u03b9\u03ac\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1", - "pad.toolbar.savedRevision.title": "\u0391\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03c5\u03bc\u03ad\u03bd\u03b5\u03c2 \u0395\u03ba\u03b4\u03cc\u03c3\u03b5\u03b9\u03c2", + "pad.toolbar.savedRevision.title": "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u0388\u03ba\u03b4\u03bf\u03c3\u03b7\u03c2", "pad.toolbar.settings.title": "\u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2", - "pad.toolbar.embed.title": "\u0395\u03bd\u03c3\u03c9\u03bc\u03b1\u03c4\u03ce\u03c3\u03c4\u03b5 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf pad", + "pad.toolbar.embed.title": "\u0395\u03bd\u03c3\u03c9\u03bc\u03ac\u03c4\u03c9\u03c3\u03b7 \u03c4\u03bf\u03c5 pad", "pad.toolbar.showusers.title": "\u0395\u03bc\u03c6\u03ac\u03bd\u03b9\u03c3\u03b7 \u03c4\u03c9\u03bd \u03c7\u03c1\u03b7\u03c3\u03c4\u03ce\u03bd \u03b1\u03c5\u03c4\u03bf\u03cd \u03c4\u03bf\u03c5 pad", "pad.colorpicker.save": "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7", "pad.colorpicker.cancel": "\u0386\u03ba\u03c5\u03c1\u03bf", @@ -78,7 +78,7 @@ "pad.share": "\u039c\u03bf\u03b9\u03c1\u03b1\u03c3\u03c4\u03b5\u03af\u03c4\u03b5 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf pad", "pad.share.readonly": "\u039c\u03cc\u03bd\u03bf \u03b3\u03b9\u03b1 \u03b1\u03bd\u03ac\u03b3\u03bd\u03c9\u03c3\u03b7", "pad.share.link": "\u03a3\u03cd\u03bd\u03b4\u03b5\u03c3\u03bc\u03bf\u03c2", - "pad.share.emebdcode": "\u0395\u03bd\u03c3\u03c9\u03bc\u03b1\u03c4\u03ce\u03c3\u03c4\u03b5 URL", + "pad.share.emebdcode": "URL \u03b5\u03bd\u03c3\u03c9\u03bc\u03ac\u03c4\u03c9\u03c3\u03b7\u03c2", "pad.chat": "\u03a3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1", "pad.chat.title": "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1 \u03c4\u03b7\u03c2 \u03c3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1\u03c2 \u03b3\u03b9\u03b1 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf pad.", "timeslider.pageTitle": "{{appTitle}} \u03a7\u03c1\u03bf\u03bd\u03bf\u03b4\u03b9\u03ac\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1", @@ -88,23 +88,23 @@ "timeslider.toolbar.exportlink.title": "\u0395\u03be\u03b1\u03b3\u03c9\u03b3\u03ae", "timeslider.exportCurrent": "\u0395\u03be\u03b1\u03b3\u03c9\u03b3\u03ae \u03c4\u03c1\u03ad\u03c7\u03bf\u03c5\u03c3\u03b1\u03c2 \u03ad\u03ba\u03b4\u03bf\u03c3\u03b7\u03c2 \u03c9\u03c2:", "timeslider.version": "\u0388\u03ba\u03b4\u03bf\u03c3\u03b7 {{version}}", - "timeslider.saved": "\u0391\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03c5\u03bc\u03ad\u03bd\u03bf\u03c2 {{month}} {{day}}, {{year}}", - "timeslider.dateformat": "{{month}} {{day}}, {{year}} {{hours}}:{{minutes}}:{{seconds}}", - "timeslider.month.january": "\u0399\u03b1\u03bd\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2", - "timeslider.month.february": "\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2", - "timeslider.month.march": "\u039c\u03ac\u03c1\u03c4\u03b9\u03bf\u03c2", - "timeslider.month.april": "\u0391\u03c0\u03c1\u03af\u03bb\u03b9\u03bf\u03c2", - "timeslider.month.may": "\u039c\u03ac\u03b9\u03bf\u03c2", - "timeslider.month.june": "\u0399\u03bf\u03cd\u03bd\u03b9\u03bf\u03c2", - "timeslider.month.july": "\u0399\u03bf\u03cd\u03bb\u03b9\u03bf\u03c2", - "timeslider.month.august": "\u0391\u03cd\u03b3\u03bf\u03c5\u03c3\u03c4\u03bf\u03c2", - "timeslider.month.september": "\u03a3\u03b5\u03c0\u03c4\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2", - "timeslider.month.october": "\u039f\u03ba\u03c4\u03ce\u03b2\u03c1\u03b9\u03bf\u03c2", - "timeslider.month.november": "\u039d\u03bf\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2", - "timeslider.month.december": "\u0394\u03b5\u03ba\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2", - "pad.savedrevs.marked": "\u0391\u03c5\u03c4\u03ae \u03b7 \u03b1\u03bd\u03b1\u03b8\u03b5\u03ce\u03c1\u03b7\u03c3\u03b7 \u03b5\u03c0\u03b9\u03c3\u03b7\u03bc\u03ac\u03bd\u03b8\u03b7\u03ba\u03b5 \u03c9\u03c2 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03c5\u03bc\u03ad\u03bd\u03b7 \u03b1\u03bd\u03b1\u03b8\u03b5\u03ce\u03c1\u03b7\u03c3\u03b7", + "timeslider.saved": "\u0391\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c4\u03b7\u03ba\u03b5 {{day}} {{month}}, {{year}}", + "timeslider.dateformat": "{{day}}\/{{month}}\/{{year}} {{hours}}:{{minutes}}:{{seconds}}", + "timeslider.month.january": "\u0399\u03b1\u03bd\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5", + "timeslider.month.february": "\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03b1\u03c1\u03af\u03bf\u03c5", + "timeslider.month.march": "\u039c\u03b1\u03c1\u03c4\u03af\u03bf\u03c5", + "timeslider.month.april": "\u0391\u03c0\u03c1\u03b9\u03bb\u03af\u03bf\u03c5", + "timeslider.month.may": "\u039c\u03b1\u0390\u03bf\u03c5", + "timeslider.month.june": "\u0399\u03bf\u03c5\u03bd\u03af\u03bf\u03c5", + "timeslider.month.july": "\u0399\u03bf\u03c5\u03bb\u03af\u03bf\u03c5", + "timeslider.month.august": "\u0391\u03c5\u03b3\u03bf\u03cd\u03c3\u03c4\u03bf\u03c5", + "timeslider.month.september": "\u03a3\u03b5\u03c0\u03c4\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5", + "timeslider.month.october": "\u039f\u03ba\u03c4\u03c9\u03b2\u03c1\u03af\u03bf\u03c5", + "timeslider.month.november": "\u039d\u03bf\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5", + "timeslider.month.december": "\u0394\u03b5\u03ba\u03b5\u03bc\u03b2\u03c1\u03af\u03bf\u03c5", + "pad.savedrevs.marked": "\u0391\u03c5\u03c4\u03ae \u03b7 \u03ad\u03ba\u03b4\u03bf\u03c3\u03b7 \u03b5\u03c0\u03b9\u03c3\u03b7\u03bc\u03ac\u03bd\u03b8\u03b7\u03ba\u03b5 \u03c9\u03c2 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03c5\u03bc\u03ad\u03bd\u03b7 \u03ad\u03ba\u03b4\u03bf\u03c3\u03b7", "pad.userlist.entername": "\u0395\u03b9\u03c3\u03ac\u03b3\u03b5\u03c4\u03b5 \u03c4\u03bf \u03cc\u03bd\u03bf\u03bc\u03ac \u03c3\u03b1\u03c2", - "pad.userlist.unnamed": "\u03b1\u03bd\u03ce\u03bd\u03c5\u03bc\u03bf", + "pad.userlist.unnamed": "\u03b1\u03bd\u03ce\u03bd\u03c5\u03bc\u03bf\u03c2", "pad.userlist.guest": "\u0395\u03c0\u03b9\u03c3\u03ba\u03ad\u03c0\u03c4\u03b7\u03c2", "pad.userlist.deny": "\u0386\u03c1\u03bd\u03b7\u03c3\u03b7", "pad.userlist.approve": "\u0388\u03b3\u03ba\u03c1\u03b9\u03c3\u03b7", diff --git a/src/locales/en.json b/src/locales/en.json index 37e07a15..bef6dfd0 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1 +1,115 @@ -{"index.newPad":"New Pad","index.createOpenPad":"or create/open a Pad with the name:","pad.toolbar.bold.title":"Bold (Ctrl-B)","pad.toolbar.italic.title":"Italic (Ctrl-I)","pad.toolbar.underline.title":"Underline (Ctrl-U)","pad.toolbar.strikethrough.title":"Strikethrough","pad.toolbar.ol.title":"Ordered list","pad.toolbar.ul.title":"Unordered List","pad.toolbar.indent.title":"Indent","pad.toolbar.unindent.title":"Outdent","pad.toolbar.undo.title":"Undo (Ctrl-Z)","pad.toolbar.redo.title":"Redo (Ctrl-Y)","pad.toolbar.clearAuthorship.title":"Clear Authorship Colors","pad.toolbar.import_export.title":"Import/Export from/to different file formats","pad.toolbar.timeslider.title":"Timeslider","pad.toolbar.savedRevision.title":"Saved Revisions","pad.toolbar.settings.title":"Settings","pad.toolbar.embed.title":"Embed this pad","pad.toolbar.showusers.title":"Show the users on this pad","pad.colorpicker.save":"Save","pad.colorpicker.cancel":"Cancel","pad.loading":"Loading...","pad.passwordRequired":"You need a password to access this pad","pad.permissionDenied":"You do not have permission to access this pad","pad.wrongPassword":"Your password was wrong","pad.settings.padSettings":"Pad Settings","pad.settings.myView":"My View","pad.settings.stickychat":"Chat always on screen","pad.settings.colorcheck":"Authorship colors","pad.settings.linenocheck":"Line numbers","pad.settings.fontType":"Font type:","pad.settings.fontType.normal":"Normal","pad.settings.fontType.monospaced":"Monospace","pad.settings.globalView":"Global View","pad.settings.language":"Language:","pad.importExport.import_export":"Import/Export","pad.importExport.import":"Upload any text file or document","pad.importExport.importSuccessful":"Successful!","pad.importExport.export":"Export current pad as:","pad.importExport.exporthtml":"HTML","pad.importExport.exportplain":"Plain text","pad.importExport.exportword":"Microsoft Word","pad.importExport.exportpdf":"PDF","pad.importExport.exportopen":"ODF (Open Document Format)","pad.importExport.exportdokuwiki":"DokuWiki","pad.importExport.abiword.innerHTML":"You only can import from plain text or html formats. For more advanced import features please install abiword.","pad.modals.connected":"Connected.","pad.modals.reconnecting":"Reconnecting to your pad..","pad.modals.forcereconnect":"Force reconnect","pad.modals.userdup":"Opened in another window","pad.modals.userdup.explanation":"This pad seems to be opened in more than one browser window on this computer.","pad.modals.userdup.advice":"Reconnect to use this window instead.","pad.modals.unauth":"Not authorized","pad.modals.unauth.explanation":"Your permissions have changed while viewing this page. Try to reconnect.","pad.modals.looping":"Disconnected.","pad.modals.looping.explanation":"There are communication problems with the synchronization server.","pad.modals.looping.cause":"Perhaps you connected through an incompatible firewall or proxy.","pad.modals.initsocketfail":"Server is unreachable.","pad.modals.initsocketfail.explanation":"Couldn't connect to the synchronization server.","pad.modals.initsocketfail.cause":"This is probably due to a problem with your browser or your internet connection.","pad.modals.slowcommit":"Disconnected.","pad.modals.slowcommit.explanation":"The server is not responding.","pad.modals.slowcommit.cause":"This could be due to problems with network connectivity.","pad.modals.deleted":"Deleted.","pad.modals.deleted.explanation":"This pad has been removed.","pad.modals.disconnected":"You have been disconnected.","pad.modals.disconnected.explanation":"The connection to the server was lost","pad.modals.disconnected.cause":"The server may be unavailable. Please notify us if this continues to happen.","pad.share":"Share this pad","pad.share.readonly":"Read only","pad.share.link":"Link","pad.share.emebdcode":"Embed URL","pad.chat":"Chat","pad.chat.title":"Open the chat for this pad.","pad.chat.loadmessages": "Load more messages","timeslider.pageTitle":"{{appTitle}} Timeslider","timeslider.toolbar.returnbutton":"Return to pad","timeslider.toolbar.authors":"Authors:","timeslider.toolbar.authorsList":"No Authors","timeslider.toolbar.exportlink.title":"Export","timeslider.exportCurrent":"Export current version as:","timeslider.version":"Version {{version}}","timeslider.saved":"Saved {{month}} {{day}}, {{year}}","timeslider.dateformat":"{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}","timeslider.month.january":"January","timeslider.month.february":"February","timeslider.month.march":"March","timeslider.month.april":"April","timeslider.month.may":"May","timeslider.month.june":"June","timeslider.month.july":"July","timeslider.month.august":"August","timeslider.month.september":"September","timeslider.month.october":"October","timeslider.month.november":"November","timeslider.month.december":"December","pad.savedrevs.marked":"This revision is now marked as a saved revision","pad.userlist.entername":"Enter your name","pad.userlist.unnamed":"unnamed","pad.userlist.guest":"Guest","pad.userlist.deny":"Deny","pad.userlist.approve":"Approve","pad.editbar.clearcolors":"Clear authorship colors on entire document?","pad.impexp.importbutton":"Import Now","pad.impexp.importing":"Importing...","pad.impexp.confirmimport":"Importing a file will overwrite the current text of the pad. Are you sure you want to proceed?","pad.impexp.convertFailed":"We were not able to import this file. Please use a different document format or copy paste manually","pad.impexp.uploadFailed":"The upload failed, please try again","pad.impexp.importfailed":"Import failed","pad.impexp.copypaste":"Please copy paste","pad.impexp.exportdisabled":"Exporting as {{type}} format is disabled. Please contact your system administrator for details."} \ No newline at end of file +{ + "index.newPad": "New Pad", + "index.createOpenPad": "or create/open a Pad with the name:", + "pad.toolbar.bold.title": "Bold (Ctrl-B)", + "pad.toolbar.italic.title": "Italic (Ctrl-I)", + "pad.toolbar.underline.title": "Underline (Ctrl-U)", + "pad.toolbar.strikethrough.title": "Strikethrough", + "pad.toolbar.ol.title": "Ordered list", + "pad.toolbar.ul.title": "Unordered List", + "pad.toolbar.indent.title": "Indent", + "pad.toolbar.unindent.title": "Outdent", + "pad.toolbar.undo.title": "Undo (Ctrl-Z)", + "pad.toolbar.redo.title": "Redo (Ctrl-Y)", + "pad.toolbar.clearAuthorship.title": "Clear Authorship Colors", + "pad.toolbar.import_export.title": "Import/Export from/to different file formats", + "pad.toolbar.timeslider.title": "Timeslider", + "pad.toolbar.savedRevision.title": "Save Revision", + "pad.toolbar.settings.title": "Settings", + "pad.toolbar.embed.title": "Embed this pad", + "pad.toolbar.showusers.title": "Show the users on this pad", + "pad.colorpicker.save": "Save", + "pad.colorpicker.cancel": "Cancel", + "pad.loading": "Loading...", + "pad.passwordRequired": "You need a password to access this pad", + "pad.permissionDenied": "You do not have permission to access this pad", + "pad.wrongPassword": "Your password was wrong", + "pad.settings.padSettings": "Pad Settings", + "pad.settings.myView": "My View", + "pad.settings.stickychat": "Chat always on screen", + "pad.settings.colorcheck": "Authorship colors", + "pad.settings.linenocheck": "Line numbers", + "pad.settings.fontType": "Font type:", + "pad.settings.fontType.normal": "Normal", + "pad.settings.fontType.monospaced": "Monospace", + "pad.settings.globalView": "Global View", + "pad.settings.language": "Language:", + "pad.importExport.import_export": "Import/Export", + "pad.importExport.import": "Upload any text file or document", + "pad.importExport.importSuccessful": "Successful!", + "pad.importExport.export": "Export current pad as:", + "pad.importExport.exporthtml": "HTML", + "pad.importExport.exportplain": "Plain text", + "pad.importExport.exportword": "Microsoft Word", + "pad.importExport.exportpdf": "PDF", + "pad.importExport.exportopen": "ODF (Open Document Format)", + "pad.importExport.exportdokuwiki": "DokuWiki", + "pad.importExport.abiword.innerHTML": "You only can import from plain text or html formats. For more advanced import features please install abiword.", + "pad.modals.connected": "Connected.", + "pad.modals.reconnecting": "Reconnecting to your pad..", + "pad.modals.forcereconnect": "Force reconnect", + "pad.modals.userdup": "Opened in another window", + "pad.modals.userdup.explanation": "This pad seems to be opened in more than one browser window on this computer.", + "pad.modals.userdup.advice": "Reconnect to use this window instead.", + "pad.modals.unauth": "Not authorized", + "pad.modals.unauth.explanation": "Your permissions have changed while viewing this page. Try to reconnect.", + "pad.modals.looping": "Disconnected.", + "pad.modals.looping.explanation": "There are communication problems with the synchronization server.", + "pad.modals.looping.cause": "Perhaps you connected through an incompatible firewall or proxy.", + "pad.modals.initsocketfail": "Server is unreachable.", + "pad.modals.initsocketfail.explanation": "Couldn't connect to the synchronization server.", + "pad.modals.initsocketfail.cause": "This is probably due to a problem with your browser or your internet connection.", + "pad.modals.slowcommit": "Disconnected.", + "pad.modals.slowcommit.explanation": "The server is not responding.", + "pad.modals.slowcommit.cause": "This could be due to problems with network connectivity.", + "pad.modals.deleted": "Deleted.", + "pad.modals.deleted.explanation": "This pad has been removed.", + "pad.modals.disconnected": "You have been disconnected.", + "pad.modals.disconnected.explanation": "The connection to the server was lost", + "pad.modals.disconnected.cause": "The server may be unavailable. Please notify us if this continues to happen.", + "pad.share": "Share this pad", + "pad.share.readonly": "Read only", + "pad.share.link": "Link", + "pad.share.emebdcode": "Embed URL", + "pad.chat": "Chat", + "pad.chat.title": "Open the chat for this pad.", + "pad.chat.loadmessages": "Load more messages", + "timeslider.pageTitle": "{{appTitle}} Timeslider", + "timeslider.toolbar.returnbutton": "Return to pad", + "timeslider.toolbar.authors": "Authors:", + "timeslider.toolbar.authorsList": "No Authors", + "timeslider.toolbar.exportlink.title": "Export", + "timeslider.exportCurrent": "Export current version as:", + "timeslider.version": "Version {{version}}", + "timeslider.saved": "Saved {{month}} {{day}}, {{year}}", + "timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}", + "timeslider.month.january": "January", + "timeslider.month.february": "February", + "timeslider.month.march": "March", + "timeslider.month.april": "April", + "timeslider.month.may": "May", + "timeslider.month.june": "June", + "timeslider.month.july": "July", + "timeslider.month.august": "August", + "timeslider.month.september": "September", + "timeslider.month.october": "October", + "timeslider.month.november": "November", + "timeslider.month.december": "December", + "timeslider.unnamedauthor": "{{num}} unnamed author", + "timeslider.unnamedauthors": "{{num}} unnamed authors", + "pad.savedrevs.marked": "This revision is now marked as a saved revision", + "pad.userlist.entername": "Enter your name", + "pad.userlist.unnamed": "unnamed", + "pad.userlist.guest": "Guest", + "pad.userlist.deny": "Deny", + "pad.userlist.approve": "Approve", + "pad.editbar.clearcolors": "Clear authorship colors on entire document?", + "pad.impexp.importbutton": "Import Now", + "pad.impexp.importing": "Importing...", + "pad.impexp.confirmimport": "Importing a file will overwrite the current text of the pad. Are you sure you want to proceed?", + "pad.impexp.convertFailed": "We were not able to import this file. Please use a different document format or copy paste manually", + "pad.impexp.uploadFailed": "The upload failed, please try again", + "pad.impexp.importfailed": "Import failed", + "pad.impexp.copypaste": "Please copy paste", + "pad.impexp.exportdisabled": "Exporting as {{type}} format is disabled. Please contact your system administrator for details." +} \ No newline at end of file diff --git a/src/locales/es.json b/src/locales/es.json index 71d201a4..f0358a90 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -4,7 +4,8 @@ "0": "Armando-Martin", "1": "Jacobo", "2": "Joker", - "4": "Xuacu" + "4": "Vivaelcelta", + "5": "Xuacu" } }, "index.newPad": "Nuevo Pad", @@ -56,6 +57,7 @@ "pad.modals.connected": "Conectado.", "pad.modals.reconnecting": "Reconectando a tu pad..", "pad.modals.forcereconnect": "Reconexi\u00f3n forzosa", + "pad.modals.userdup": "Abierto en otra ventana", "pad.modals.userdup.explanation": "Este pad parece estar abierto en m\u00e1s de una ventana de tu navegador.", "pad.modals.userdup.advice": "Reconectar para usar esta ventana.", "pad.modals.unauth": "No autorizado.", @@ -80,10 +82,12 @@ "pad.share.emebdcode": "Incrustar URL", "pad.chat": "Chat", "pad.chat.title": "Abrir el chat para este pad.", + "pad.chat.loadmessages": "Cargar m\u00e1s mensajes", "timeslider.pageTitle": "{{appTitle}} L\u00ednea de tiempo", "timeslider.toolbar.returnbutton": "Volver al pad", "timeslider.toolbar.authors": "Autores:", "timeslider.toolbar.authorsList": "Sin autores", + "timeslider.toolbar.exportlink.title": "Exportar", "timeslider.exportCurrent": "Exportar la versi\u00f3n actual como:", "timeslider.version": "Versi\u00f3n {{version}}", "timeslider.saved": "Guardado el {{day}} de {{month}} de {{year}}", diff --git a/src/locales/fi.json b/src/locales/fi.json index 9a644bda..74f7e36c 100644 --- a/src/locales/fi.json +++ b/src/locales/fi.json @@ -5,7 +5,8 @@ "1": "Jl", "2": "Nedergard", "3": "Nike", - "5": "VezonThunder" + "5": "Veikk0.ma", + "6": "VezonThunder" } }, "index.newPad": "Uusi muistio", @@ -82,6 +83,7 @@ "pad.share.emebdcode": "Upotusosoite", "pad.chat": "Keskustelu", "pad.chat.title": "Avaa keskustelu nykyisest\u00e4 muistiosta.", + "pad.chat.loadmessages": "Lataa lis\u00e4\u00e4 viestej\u00e4", "timeslider.pageTitle": "{{appTitle}} -aikajana", "timeslider.toolbar.returnbutton": "Palaa muistioon", "timeslider.toolbar.authors": "Tekij\u00e4t:", diff --git a/src/locales/fr.json b/src/locales/fr.json index f861150d..05ec1ab3 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -87,6 +87,7 @@ "pad.share.emebdcode": "Lien \u00e0 int\u00e9grer", "pad.chat": "Chat", "pad.chat.title": "Ouvrir le chat associ\u00e9 \u00e0 ce pad.", + "pad.chat.loadmessages": "Charger davantage de messages", "timeslider.pageTitle": "Historique dynamique de {{appTitle}}", "timeslider.toolbar.returnbutton": "Retour \u00e0 ce Pad.", "timeslider.toolbar.authors": "Auteurs :", diff --git a/src/locales/gl.json b/src/locales/gl.json index 2cd30e33..7f2e5a56 100644 --- a/src/locales/gl.json +++ b/src/locales/gl.json @@ -78,6 +78,7 @@ "pad.share.emebdcode": "Incorporar o URL", "pad.chat": "Chat", "pad.chat.title": "Abrir o chat deste documento.", + "pad.chat.loadmessages": "Cargar m\u00e1is mensaxes", "timeslider.pageTitle": "Li\u00f1a do tempo de {{appTitle}}", "timeslider.toolbar.returnbutton": "Volver ao documento", "timeslider.toolbar.authors": "Autores:", diff --git a/src/locales/he.json b/src/locales/he.json index 2a265791..75ebff1b 100644 --- a/src/locales/he.json +++ b/src/locales/he.json @@ -42,6 +42,7 @@ "pad.settings.language": "\u05e9\u05e4\u05d4:", "pad.importExport.import_export": "\u05d9\u05d9\u05d1\u05d5\u05d0\/\u05d9\u05d9\u05e6\u05d5\u05d0", "pad.importExport.import": "\u05d4\u05e2\u05dc\u05d0\u05ea \u05db\u05dc \u05e7\u05d5\u05d1\u05e5 \u05d8\u05e7\u05e1\u05d8 \u05d0\u05d5 \u05de\u05e1\u05de\u05da", + "pad.importExport.importSuccessful": "\u05d6\u05d4 \u05e2\u05d1\u05d3!", "pad.importExport.export": "\u05d9\u05d9\u05e6\u05d5\u05d0 \u05d4\u05e4\u05e0\u05e7\u05e1 \u05d4\u05e0\u05d5\u05db\u05d7\u05d9 \u05d1\u05ea\u05d5\u05e8:", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "\u05d8\u05e7\u05e1\u05d8 \u05e8\u05d2\u05d9\u05dc", @@ -53,6 +54,7 @@ "pad.modals.connected": "\u05de\u05d7\u05d5\u05d1\u05db\u05e8.", "pad.modals.reconnecting": "\u05de\u05ea\u05d1\u05e6\u05e2 \u05d7\u05d9\u05d1\u05d5\u05e8 \u05de\u05d7\u05d3\u05e9...", "pad.modals.forcereconnect": "\u05d7\u05d9\u05d1\u05d5\u05e8 \u05db\u05e4\u05d5\u05d9 \u05de\u05d7\u05d3\u05e9", + "pad.modals.userdup": "\u05e4\u05ea\u05d5\u05d7 \u05d1\u05d7\u05dc\u05d5\u05df \u05d0\u05d7\u05e8", "pad.modals.userdup.explanation": "\u05e0\u05e8\u05d0\u05d4 \u05e9\u05d4\u05e4\u05e0\u05e7\u05e1 \u05d4\u05d6\u05d4 \u05e4\u05ea\u05d5\u05d7 \u05d1\u05d9\u05d5\u05ea\u05e8 \u05de\u05d7\u05dc\u05d5\u05df \u05d3\u05e4\u05d3\u05e4\u05df \u05d0\u05d7\u05d3 \u05d1\u05de\u05d7\u05e9\u05d1 \u05d4\u05d6\u05d4.", "pad.modals.userdup.advice": "\u05dc\u05d4\u05ea\u05d7\u05d1\u05e8 \u05de\u05d7\u05d3\u05e9 \u05d1\u05d0\u05de\u05e6\u05e2\u05d5\u05ea \u05d4\u05d7\u05dc\u05d5\u05df \u05d4\u05d6\u05d4.", "pad.modals.unauth": "\u05d0\u05d9\u05df \u05d4\u05e8\u05e9\u05d0\u05d4", @@ -99,8 +101,18 @@ "timeslider.month.november": "\u05e0\u05d5\u05d1\u05de\u05d1\u05e8", "timeslider.month.december": "\u05d3\u05e6\u05de\u05d1\u05e8", "pad.savedrevs.marked": "\u05d2\u05e8\u05e1\u05d4 \u05d6\u05d5 \u05de\u05e1\u05d5\u05de\u05e0\u05ea \u05db\u05d2\u05e8\u05e1\u05d4 \u05e9\u05de\u05d5\u05e8\u05d4", + "pad.userlist.entername": "\u05e0\u05d0 \u05dc\u05d4\u05d6\u05d9\u05df \u05d0\u05ea \u05e9\u05de\u05da", "pad.userlist.unnamed": "\u05dc\u05dc\u05d0 \u05e9\u05dd", "pad.userlist.guest": "\u05d0\u05d5\u05e8\u05d7", + "pad.userlist.deny": "\u05dc\u05d3\u05d7\u05d5\u05ea", + "pad.userlist.approve": "\u05dc\u05d0\u05e9\u05e8", + "pad.editbar.clearcolors": "\u05dc\u05e0\u05e7\u05d5\u05ea \u05e6\u05d1\u05e2\u05d9\u05dd \u05dc\u05e1\u05d9\u05de\u05d5\u05df \u05db\u05d5\u05ea\u05d1\u05d9\u05dd \u05d1\u05db\u05dc \u05d4\u05de\u05e1\u05de\u05da?", "pad.impexp.importbutton": "\u05dc\u05d9\u05d9\u05d1\u05d0 \u05db\u05e2\u05ea", - "pad.impexp.confirmimport": "\u05d9\u05d1\u05d5\u05d0 \u05e9\u05dc \u05e7\u05d5\u05d1\u05e5 \u05d9\u05d1\u05d8\u05dc \u05d0\u05ea \u05d4\u05d8\u05e7\u05e1\u05d8 \u05d4\u05e0\u05d5\u05db\u05d7\u05d9 \u05d1\u05e4\u05e0\u05e7\u05e1. \u05d4\u05d0\u05dd \u05d0\u05ea\u05dd \u05d1\u05d8\u05d5\u05d7\u05d9\u05dd \u05e9\u05d1\u05e8\u05e6\u05d5\u05e0\u05db\u05dd \u05dc\u05d4\u05de\u05e9\u05d9\u05da?" + "pad.impexp.importing": "\u05d9\u05d9\u05d1\u05d5\u05d0...", + "pad.impexp.confirmimport": "\u05d9\u05d1\u05d5\u05d0 \u05e9\u05dc \u05e7\u05d5\u05d1\u05e5 \u05d9\u05d1\u05d8\u05dc \u05d0\u05ea \u05d4\u05d8\u05e7\u05e1\u05d8 \u05d4\u05e0\u05d5\u05db\u05d7\u05d9 \u05d1\u05e4\u05e0\u05e7\u05e1. \u05d4\u05d0\u05dd \u05d0\u05ea\u05dd \u05d1\u05d8\u05d5\u05d7\u05d9\u05dd \u05e9\u05d1\u05e8\u05e6\u05d5\u05e0\u05db\u05dd \u05dc\u05d4\u05de\u05e9\u05d9\u05da?", + "pad.impexp.convertFailed": "\u05dc\u05d0 \u05d4\u05ea\u05d7\u05dc\u05dc\u05d0 \u05d4\u05e6\u05dc\u05d7\u05e0\u05d5 \u05dc\u05d9\u05d9\u05d1\u05d0 \u05d0\u05ea \u05d4\u05e7\u05d5\u05d1\u05e5 \u05d4\u05d6\u05d4. \u05e0\u05d0 \u05dc\u05d4\u05e9\u05ea\u05de\u05e9 \u05d1\u05ea\u05e1\u05d3\u05d9\u05e8 \u05de\u05e1\u05de\u05da \u05e9\u05d5\u05e0\u05d4 \u05d0\u05d5 \u05dc\u05d4\u05e2\u05ea\u05d9\u05e7 \u05d5\u05dc\u05d4\u05d3\u05d1\u05d9\u05e7 \u05d9\u05d3\u05e0\u05d9\u05ea", + "pad.impexp.uploadFailed": "\u05d4\u05d4\u05e2\u05dc\u05d0\u05d4 \u05e0\u05db\u05e9\u05dc\u05d4, \u05e0\u05d0 \u05dc\u05e0\u05e1\u05d5\u05ea \u05e9\u05d5\u05d1", + "pad.impexp.importfailed": "\u05d4\u05d9\u05d9\u05d1\u05d5\u05d0 \u05e0\u05db\u05e9\u05dc", + "pad.impexp.copypaste": "\u05e0\u05d0 \u05dc\u05d4\u05e2\u05ea\u05d9\u05e7 \u05d5\u05dc\u05d4\u05d3\u05d1\u05d9\u05e7", + "pad.impexp.exportdisabled": "\u05d9\u05d9\u05e6\u05d5\u05d0 \u05d1\u05ea\u05e1\u05d3\u05d9\u05e8 {{type}} \u05d0\u05d9\u05e0\u05d5 \u05e4\u05e2\u05d9\u05dc. \u05de\u05e0\u05d4\u05dc \u05d4\u05de\u05e2\u05e8\u05db\u05ea \u05e9\u05dc\u05da \u05d9\u05d5\u05db\u05dc \u05dc\u05e1\u05e4\u05e8 \u05dc\u05da \u05e2\u05dc \u05d6\u05d4 \u05e2\u05d5\u05d3 \u05e4\u05e8\u05d8\u05d9\u05dd." } \ No newline at end of file diff --git a/src/locales/it.json b/src/locales/it.json index 8f2a9c99..c60678db 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -81,6 +81,7 @@ "pad.share.emebdcode": "Incorpora URL", "pad.chat": "Chat", "pad.chat.title": "Apri la chat per questo Pad.", + "pad.chat.loadmessages": "Carica altri messaggi", "timeslider.pageTitle": "Cronologia {{appTitle}}", "timeslider.toolbar.returnbutton": "Ritorna al Pad", "timeslider.toolbar.authors": "Autori:", diff --git a/src/locales/ja.json b/src/locales/ja.json index 36c2328c..1954b979 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -78,6 +78,7 @@ "pad.share.emebdcode": "\u57cb\u3081\u8fbc\u307f\u7528 URL", "pad.chat": "\u30c1\u30e3\u30c3\u30c8", "pad.chat.title": "\u3053\u306e\u30d1\u30c3\u30c9\u306e\u30c1\u30e3\u30c3\u30c8\u3092\u958b\u304d\u307e\u3059\u3002", + "pad.chat.loadmessages": "\u305d\u306e\u4ed6\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u8aad\u307f\u8fbc\u3080", "timeslider.pageTitle": "{{appTitle}} \u30bf\u30a4\u30e0\u30b9\u30e9\u30a4\u30c0\u30fc", "timeslider.toolbar.returnbutton": "\u30d1\u30c3\u30c9\u306b\u623b\u308b", "timeslider.toolbar.authors": "\u4f5c\u8005:", diff --git a/src/locales/ko.json b/src/locales/ko.json index f9e69695..9e436b0c 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -78,6 +78,7 @@ "pad.share.emebdcode": "URL \ud3ec\ud568", "pad.chat": "\ub300\ud654", "pad.chat.title": "\uc774 \ud328\ub4dc\uc5d0 \ub300\ud654\ub97c \uc5fd\ub2c8\ub2e4.", + "pad.chat.loadmessages": "\ub354 \ub9ce\uc740 \uba54\uc2dc\uc9c0 \ubd88\ub7ec\uc624\uae30", "timeslider.pageTitle": "{{appTitle}} \uc2dc\uac04\uc2ac\ub77c\uc774\ub354", "timeslider.toolbar.returnbutton": "\ud328\ub4dc\ub85c \ub3cc\uc544\uac00\uae30", "timeslider.toolbar.authors": "\uc800\uc790:", diff --git a/src/locales/mk.json b/src/locales/mk.json index 1ed2a47d..9dd5e725 100644 --- a/src/locales/mk.json +++ b/src/locales/mk.json @@ -79,6 +79,7 @@ "pad.share.emebdcode": "\u0412\u043c\u0435\u0442\u043d\u0438 URL", "pad.chat": "\u0420\u0430\u0437\u0433\u043e\u0432\u043e\u0440", "pad.chat.title": "\u041e\u0442\u0432\u043e\u0440\u0438 \u0433\u043e \u0440\u0430\u0437\u0433\u043e\u0432\u043e\u0440\u043e\u0442 \u0437\u0430 \u043e\u0432\u0430\u0430 \u0442\u0435\u0442\u0440\u0430\u0442\u043a\u0430.", + "pad.chat.loadmessages": "\u0412\u0447\u0438\u0442\u0430\u0458 \u0443\u0448\u0442\u0435 \u043f\u043e\u0440\u0430\u043a\u0438", "timeslider.pageTitle": "{{appTitle}} \u0418\u0441\u0442\u043e\u0440\u0438\u0441\u043a\u0438 \u043f\u0440\u0435\u0433\u043b\u0435\u0434", "timeslider.toolbar.returnbutton": "\u041d\u0430\u0437\u0430\u0434 \u043d\u0430 \u0442\u0435\u0442\u0440\u0430\u0442\u043a\u0430\u0442\u0430", "timeslider.toolbar.authors": "\u0410\u0432\u0442\u043e\u0440\u0438:", diff --git a/src/locales/ml.json b/src/locales/ml.json index 0c39d6f8..4741fe77 100644 --- a/src/locales/ml.json +++ b/src/locales/ml.json @@ -1,6 +1,7 @@ { "@metadata": { "authors": [ + "Hrishikesh.kb", "Praveenp", "Santhosh.thottingal" ] @@ -27,11 +28,14 @@ "pad.colorpicker.save": "\u0d38\u0d47\u0d35\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d15", "pad.colorpicker.cancel": "\u0d31\u0d26\u0d4d\u0d26\u0d3e\u0d15\u0d4d\u0d15\u0d41\u0d15", "pad.loading": "\u0d36\u0d47\u0d16\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d41...", + "pad.passwordRequired": "\u0d08 \u0d2a\u0d3e\u0d21\u0d4d \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d24\u0d3f\u0d28\u0d3e\u0d2f\u0d3f \u0d12\u0d30\u0d41 \u0d30\u0d39\u0d38\u0d4d\u0d2f\u0d35\u0d3e\u0d15\u0d4d\u0d15\u0d4d \u0d28\u0d7d\u0d15\u0d47\u0d23\u0d4d\u0d1f\u0d24\u0d3e\u0d23\u0d4d", + "pad.permissionDenied": "\u0d08 \u0d2a\u0d3e\u0d21\u0d4d \u0d15\u0d3e\u0d23\u0d41\u0d35\u0d3e\u0d7b \u0d24\u0d3e\u0d19\u0d4d\u0d15\u0d7e\u0d15\u0d4d\u0d15\u0d4d \u0d05\u0d28\u0d41\u0d2e\u0d24\u0d3f\u0d2f\u0d3f\u0d32\u0d4d\u0d32", + "pad.wrongPassword": "\u0d24\u0d3e\u0d19\u0d4d\u0d15\u0d7e \u0d28\u0d32\u0d4d\u0d15\u0d3f\u0d2f \u0d30\u0d39\u0d38\u0d4d\u0d2f\u0d35\u0d3e\u0d15\u0d4d\u0d15\u0d4d \u0d24\u0d46\u0d31\u0d4d\u0d31\u0d3e\u0d2f\u0d3f\u0d30\u0d41\u0d28\u0d4d\u0d28\u0d41", "pad.settings.padSettings": "\u0d2a\u0d3e\u0d21\u0d4d \u0d38\u0d1c\u0d4d\u0d1c\u0d40\u0d15\u0d30\u0d23\u0d19\u0d4d\u0d19\u0d7e", "pad.settings.myView": "\u0d0e\u0d28\u0d4d\u0d31\u0d46 \u0d15\u0d3e\u0d34\u0d4d\u0d1a", "pad.settings.stickychat": "\u0d24\u0d24\u0d4d\u0d38\u0d2e\u0d2f\u0d02 \u0d38\u0d02\u0d35\u0d3e\u0d26\u0d02 \u0d0e\u0d2a\u0d4d\u0d2a\u0d4b\u0d34\u0d41\u0d02 \u0d38\u0d4d\u0d15\u0d4d\u0d30\u0d40\u0d28\u0d3f\u0d7d \u0d15\u0d3e\u0d23\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15", "pad.settings.colorcheck": "\u0d0e\u0d34\u0d41\u0d24\u0d4d\u0d24\u0d41\u0d15\u0d3e\u0d7c\u0d15\u0d4d\u0d15\u0d41\u0d33\u0d4d\u0d33 \u0d28\u0d3f\u0d31\u0d19\u0d4d\u0d19\u0d7e", - "pad.settings.linenocheck": "\u0d0e\u0d23\u0d4d\u0d23\u0d2e\u0d3f\u0d1f\u0d4d\u0d1f \u0d35\u0d30\u0d3f\u0d15\u0d7e", + "pad.settings.linenocheck": "\u0d35\u0d30\u0d3f\u0d15\u0d33\u0d41\u0d1f\u0d46 \u0d15\u0d4d\u0d30\u0d2e\u0d38\u0d02\u0d16\u0d4d\u0d2f", "pad.settings.fontType": "\u0d2b\u0d4b\u0d23\u0d4d\u0d1f\u0d4d \u0d24\u0d30\u0d02:", "pad.settings.fontType.normal": "\u0d38\u0d3e\u0d27\u0d3e\u0d30\u0d23\u0d02", "pad.settings.fontType.monospaced": "\u0d2e\u0d4b\u0d23\u0d4b\u0d38\u0d4d\u0d2a\u0d47\u0d38\u0d4d", @@ -50,6 +54,7 @@ "pad.modals.connected": "\u0d2c\u0d28\u0d4d\u0d27\u0d3f\u0d2a\u0d4d\u0d2a\u0d3f\u0d1a\u0d4d\u0d1a\u0d3f\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d41.", "pad.modals.reconnecting": "\u0d24\u0d3e\u0d19\u0d4d\u0d15\u0d33\u0d41\u0d1f\u0d46 \u0d2a\u0d3e\u0d21\u0d3f\u0d32\u0d47\u0d2f\u0d4d\u0d15\u0d4d\u0d15\u0d4d \u0d35\u0d40\u0d23\u0d4d\u0d1f\u0d41\u0d02 \u0d2c\u0d28\u0d4d\u0d27\u0d3f\u0d2a\u0d4d\u0d2a\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d41...", "pad.modals.forcereconnect": "\u0d0e\u0d28\u0d4d\u0d24\u0d3e\u0d2f\u0d3e\u0d32\u0d41\u0d02 \u0d2c\u0d28\u0d4d\u0d27\u0d3f\u0d2a\u0d4d\u0d2a\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15", + "pad.modals.userdup": "\u0d2e\u0d31\u0d4d\u0d31\u0d4a\u0d30\u0d41 \u0d1c\u0d3e\u0d32\u0d15\u0d24\u0d4d\u0d24\u0d3f\u0d7d \u0d24\u0d41\u0d31\u0d28\u0d4d\u0d28\u0d3f\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d41", "pad.modals.userdup.explanation": "\u0d08 \u0d15\u0d2e\u0d4d\u0d2a\u0d4d\u0d2f\u0d42\u0d1f\u0d4d\u0d1f\u0d31\u0d3f\u0d7d \u0d08 \u0d2a\u0d3e\u0d21\u0d4d \u0d12\u0d28\u0d4d\u0d28\u0d3f\u0d32\u0d27\u0d3f\u0d15\u0d02 \u0d2c\u0d4d\u0d30\u0d57\u0d38\u0d7c \u0d1c\u0d3e\u0d32\u0d15\u0d19\u0d4d\u0d19\u0d33\u0d3f\u0d7d \u0d24\u0d41\u0d31\u0d28\u0d4d\u0d28\u0d24\u0d3e\u0d2f\u0d3f \u0d15\u0d3e\u0d23\u0d41\u0d28\u0d4d\u0d28\u0d41.", "pad.modals.userdup.advice": "\u0d08 \u0d1c\u0d3e\u0d32\u0d15\u0d02 \u0d24\u0d28\u0d4d\u0d28\u0d46 \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d15\u0d4d\u0d15\u0d3e\u0d28\u0d3e\u0d2f\u0d3f \u0d2c\u0d28\u0d4d\u0d27\u0d3f\u0d2a\u0d4d\u0d2a\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15", "pad.modals.unauth": "\u0d05\u0d28\u0d41\u0d35\u0d3e\u0d26\u0d2e\u0d3f\u0d32\u0d4d\u0d32", @@ -78,9 +83,11 @@ "timeslider.toolbar.returnbutton": "\u0d2a\u0d3e\u0d21\u0d3f\u0d32\u0d47\u0d15\u0d4d\u0d15\u0d4d \u0d24\u0d3f\u0d30\u0d3f\u0d1a\u0d4d\u0d1a\u0d41\u0d2a\u0d4b\u0d35\u0d41\u0d15", "timeslider.toolbar.authors": "\u0d30\u0d1a\u0d2f\u0d3f\u0d24\u0d3e\u0d15\u0d4d\u0d15\u0d7e:", "timeslider.toolbar.authorsList": "\u0d06\u0d30\u0d41\u0d02 \u0d0e\u0d34\u0d41\u0d24\u0d3f\u0d2f\u0d3f\u0d1f\u0d4d\u0d1f\u0d3f\u0d32\u0d4d\u0d32", + "timeslider.toolbar.exportlink.title": "\u0d15\u0d2f\u0d31\u0d4d\u0d31\u0d41\u0d2e\u0d24\u0d3f", "timeslider.exportCurrent": "\u0d08 \u0d2a\u0d24\u0d3f\u0d2a\u0d4d\u0d2a\u0d4d \u0d07\u0d19\u0d4d\u0d19\u0d28\u0d46 \u0d0e\u0d1f\u0d41\u0d15\u0d4d\u0d15\u0d41\u0d15:", "timeslider.version": "\u0d2a\u0d24\u0d3f\u0d2a\u0d4d\u0d2a\u0d4d {{version}}", "timeslider.saved": "\u0d38\u0d47\u0d35\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d24\u0d24\u0d4d {{month}} {{day}}, {{year}}", + "timeslider.dateformat": "{{month}}\/{{day}}\/{{year}} {{hours}}:{{minutes}}:{{seconds}}", "timeslider.month.january": "\u0d1c\u0d28\u0d41\u0d35\u0d30\u0d3f", "timeslider.month.february": "\u0d2b\u0d46\u0d2c\u0d4d\u0d30\u0d41\u0d35\u0d30\u0d3f", "timeslider.month.march": "\u0d2e\u0d3e\u0d7c\u0d1a\u0d4d\u0d1a\u0d4d", @@ -93,9 +100,19 @@ "timeslider.month.october": "\u0d12\u0d15\u0d4d\u0d1f\u0d4b\u0d2c\u0d7c", "timeslider.month.november": "\u0d28\u0d35\u0d02\u0d2c\u0d7c", "timeslider.month.december": "\u0d21\u0d3f\u0d38\u0d02\u0d2c\u0d7c", - "pad.userlist.entername": "\u0d28\u0d3f\u0d19\u0d4d\u0d19\u0d33\u0d41\u0d1f\u0d46 \u0d2a\u0d47\u0d30\u0d4d", + "pad.savedrevs.marked": "\u0d08 \u0d28\u0d3e\u0d7e\u0d2a\u0d4d\u0d2a\u0d24\u0d3f\u0d2a\u0d4d\u0d2a\u0d4d \u0d38\u0d47\u0d35\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d24\u0d3f\u0d1f\u0d4d\u0d1f\u0d41\u0d33\u0d4d\u0d33 \u0d28\u0d3e\u0d7e\u0d2a\u0d4d\u0d2a\u0d24\u0d3f\u0d2a\u0d4d\u0d2a\u0d3e\u0d2f\u0d3f \u0d05\u0d1f\u0d2f\u0d3e\u0d33\u0d2a\u0d4d\u0d2a\u0d46\u0d1f\u0d41\u0d24\u0d4d\u0d24\u0d3f\u0d2f\u0d3f\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d41", + "pad.userlist.entername": "\u0d24\u0d3e\u0d19\u0d4d\u0d15\u0d33\u0d41\u0d1f\u0d46 \u0d2a\u0d47\u0d30\u0d4d \u0d28\u0d7d\u0d15\u0d41\u0d15", "pad.userlist.unnamed": "\u0d2a\u0d47\u0d30\u0d3f\u0d32\u0d4d\u0d32\u0d3e\u0d24\u0d4d\u0d24", "pad.userlist.guest": "\u0d05\u0d24\u0d3f\u0d25\u0d3f", - "pad.userlist.deny": "\u0d24\u0d33\u0d4d\u0d33\u0d3f\u0d15\u0d4d\u0d15\u0d33\u0d2f\u0d41\u0d15", - "pad.userlist.approve": "\u0d05\u0d02\u0d17\u0d40\u0d15\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15" + "pad.userlist.deny": "\u0d28\u0d3f\u0d30\u0d38\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15", + "pad.userlist.approve": "\u0d05\u0d02\u0d17\u0d40\u0d15\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15", + "pad.editbar.clearcolors": "\u0d21\u0d4b\u0d15\u0d4d\u0d2f\u0d41\u0d2e\u0d46\u0d28\u0d4d\u0d31\u0d3f\u0d7d \u0d30\u0d1a\u0d2f\u0d3f\u0d24\u0d3e\u0d15\u0d4d\u0d15\u0d33\u0d46 \u0d38\u0d42\u0d1a\u0d3f\u0d2a\u0d4d\u0d2a\u0d3f\u0d15\u0d4d\u0d15\u0d3e\u0d28\u0d3e\u0d2f\u0d3f \u0d28\u0d7d\u0d15\u0d3f\u0d2f\u0d3f\u0d1f\u0d4d\u0d1f\u0d41\u0d33\u0d4d\u0d33 \u0d28\u0d3f\u0d31\u0d19\u0d4d\u0d19\u0d7e \u0d12\u0d34\u0d3f\u0d35\u0d3e\u0d15\u0d4d\u0d15\u0d1f\u0d4d\u0d1f\u0d46?", + "pad.impexp.importbutton": "\u0d07\u0d31\u0d15\u0d4d\u0d15\u0d41\u0d2e\u0d24\u0d3f \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d15", + "pad.impexp.importing": "\u0d07\u0d31\u0d15\u0d4d\u0d15\u0d41\u0d2e\u0d24\u0d3f \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d28\u0d4d\u0d28\u0d41...", + "pad.impexp.confirmimport": "\u0d12\u0d30\u0d41 \u0d2a\u0d4d\u0d30\u0d2e\u0d3e\u0d23\u0d02 \u0d07\u0d31\u0d15\u0d4d\u0d15\u0d41\u0d2e\u0d24\u0d3f \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d28\u0d4d\u0d28\u0d24\u0d4d \u0d28\u0d3f\u0d32\u0d35\u0d3f\u0d32\u0d41\u0d33\u0d4d\u0d33 \u0d0e\u0d34\u0d41\u0d24\u0d4d\u0d24\u0d41\u0d15\u0d7e \u0d28\u0d37\u0d4d\u0d1f\u0d2a\u0d4d\u0d2a\u0d46\u0d1f\u0d3e\u0d28\u0d3f\u0d1f\u0d2f\u0d3e\u0d15\u0d4d\u0d15\u0d41\u0d02, \u0d24\u0d41\u0d1f\u0d30\u0d23\u0d2e\u0d46\u0d28\u0d4d\u0d28\u0d4d \u0d09\u0d31\u0d2a\u0d4d\u0d2a\u0d3e\u0d23\u0d4b?", + "pad.impexp.convertFailed": "\u0d08 \u0d2a\u0d4d\u0d30\u0d2e\u0d3e\u0d23\u0d02 \u0d07\u0d31\u0d15\u0d4d\u0d15\u0d41\u0d2e\u0d24\u0d3f \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d3e\u0d7b \u0d38\u0d3e\u0d27\u0d3f\u0d1a\u0d4d\u0d1a\u0d3f\u0d32\u0d4d\u0d32. \u0d26\u0d2f\u0d35\u0d3e\u0d2f\u0d3f \u0d2e\u0d31\u0d4d\u0d31\u0d4a\u0d30\u0d41 \u0d21\u0d4b\u0d15\u0d4d\u0d2f\u0d41\u0d2e\u0d46\u0d28\u0d4d\u0d31\u0d4d \u0d2b\u0d4b\u0d7c\u0d2e\u0d3e\u0d31\u0d4d\u0d31\u0d4d \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15\u0d2f\u0d4b, \u0d38\u0d4d\u0d35\u0d28\u0d4d\u0d24\u0d2e\u0d3e\u0d2f\u0d3f \u0d2a\u0d15\u0d7c\u0d24\u0d4d\u0d24\u0d3f \u0d1a\u0d47\u0d7c\u0d15\u0d4d\u0d15\u0d41\u0d15\u0d2f\u0d4b \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d15", + "pad.impexp.uploadFailed": "\u0d05\u0d2a\u0d4d\u200c\u200c\u0d32\u0d4b\u0d21\u0d4d \u0d2a\u0d30\u0d3e\u0d1c\u0d2f\u0d2a\u0d4d\u0d2a\u0d46\u0d1f\u0d4d\u0d1f\u0d41. \u0d26\u0d2f\u0d35\u0d3e\u0d2f\u0d3f \u0d35\u0d40\u0d23\u0d4d\u0d1f\u0d41\u0d02 \u0d36\u0d4d\u0d30\u0d2e\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15", + "pad.impexp.importfailed": "\u0d07\u0d31\u0d15\u0d4d\u0d15\u0d41\u0d2e\u0d24\u0d3f \u0d2a\u0d30\u0d3e\u0d1c\u0d2f\u0d2a\u0d4d\u0d2a\u0d46\u0d1f\u0d4d\u0d1f\u0d41", + "pad.impexp.copypaste": "\u0d26\u0d2f\u0d35\u0d3e\u0d2f\u0d3f \u0d2a\u0d15\u0d7c\u0d24\u0d4d\u0d24\u0d3f \u0d1a\u0d47\u0d7c\u0d15\u0d4d\u0d15\u0d41\u0d15", + "pad.impexp.exportdisabled": "{{type}} \u0d2b\u0d4b\u0d7c\u0d2e\u0d3e\u0d31\u0d4d\u0d31\u0d3f\u0d7d \u0d15\u0d2f\u0d31\u0d4d\u0d31\u0d41\u0d2e\u0d24\u0d3f \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d28\u0d4d\u0d28\u0d24\u0d4d \u0d24\u0d1f\u0d1e\u0d4d\u0d1e\u0d3f\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d41. \u0d15\u0d42\u0d1f\u0d41\u0d24\u0d7d \u0d35\u0d3f\u0d35\u0d30\u0d19\u0d4d\u0d19\u0d7e\u0d15\u0d4d\u0d15\u0d4d \u0d24\u0d3e\u0d19\u0d4d\u0d15\u0d33\u0d41\u0d1f\u0d46 \u0d38\u0d3f\u0d38\u0d4d\u0d31\u0d4d\u0d31\u0d02 \u0d05\u0d21\u0d4d\u0d2e\u0d3f\u0d28\u0d3f\u0d38\u0d4d\u0d1f\u0d4d\u0d30\u0d47\u0d31\u0d4d\u0d31\u0d31\u0d41\u0d2e\u0d3e\u0d2f\u0d3f \u0d2c\u0d28\u0d4d\u0d27\u0d2a\u0d4d\u0d2a\u0d46\u0d1f\u0d41\u0d15." } \ No newline at end of file diff --git a/src/locales/nl.json b/src/locales/nl.json index 14ba42c0..9b1c773b 100644 --- a/src/locales/nl.json +++ b/src/locales/nl.json @@ -78,6 +78,7 @@ "pad.share.emebdcode": "URL insluiten", "pad.chat": "Chatten", "pad.chat.title": "Chat voor dit pad opnenen", + "pad.chat.loadmessages": "Meer berichten laden", "timeslider.pageTitle": "Tijdlijn voor {{appTitle}}", "timeslider.toolbar.returnbutton": "Terug naar pad", "timeslider.toolbar.authors": "Auteurs:", @@ -99,6 +100,8 @@ "timeslider.month.october": "oktober", "timeslider.month.november": "november", "timeslider.month.december": "december", + "timeslider.unnamedauthor": "{{num}} onbekende auteur", + "timeslider.unnamedauthors": "{{num}} onbekende auteurs", "pad.savedrevs.marked": "Deze versie is nu gemarkeerd als opgeslagen versie", "pad.userlist.entername": "Geef uw naam op", "pad.userlist.unnamed": "zonder naam", diff --git a/src/locales/oc.json b/src/locales/oc.json new file mode 100644 index 00000000..08390825 --- /dev/null +++ b/src/locales/oc.json @@ -0,0 +1,118 @@ +{ + "@metadata": { + "authors": [ + "Cedric31" + ] + }, + "index.newPad": "Pad nov\u00e8l", + "index.createOpenPad": "o crear\/dobrir un Pad intitulat :", + "pad.toolbar.bold.title": "Gras (Ctrl-B)", + "pad.toolbar.italic.title": "Italica (Ctrl-I)", + "pad.toolbar.underline.title": "Soslinhat (Ctrl-U)", + "pad.toolbar.strikethrough.title": "Raiat", + "pad.toolbar.ol.title": "Lista ordenada", + "pad.toolbar.ul.title": "Lista amb de piuses", + "pad.toolbar.indent.title": "Indentar", + "pad.toolbar.unindent.title": "Desindentar", + "pad.toolbar.undo.title": "Anullar (Ctrl-Z)", + "pad.toolbar.redo.title": "Restablir (Ctrl-Y)", + "pad.toolbar.clearAuthorship.title": "Escafar las colors qu'identifican los autors", + "pad.toolbar.import_export.title": "Importar\/Exportar de\/cap a un format de fichi\u00e8r diferent", + "pad.toolbar.timeslider.title": "Istoric dinamic", + "pad.toolbar.savedRevision.title": "Versions enregistradas", + "pad.toolbar.settings.title": "Param\u00e8tres", + "pad.toolbar.embed.title": "Integrar aqueste Pad", + "pad.toolbar.showusers.title": "Afichar los utilizaires del Pad", + "pad.colorpicker.save": "Enregistrar", + "pad.colorpicker.cancel": "Anullar", + "pad.loading": "Cargament...", + "pad.passwordRequired": "Av\u00e8tz besonh d'un senhal per accedir a aqueste Pad", + "pad.permissionDenied": "Vos es pas perm\u00e9s d\u2019accedir a aqueste Pad.", + "pad.wrongPassword": "Senhal incorr\u00e8cte", + "pad.settings.padSettings": "Param\u00e8tres del Pad", + "pad.settings.myView": "Ma vista", + "pad.settings.stickychat": "Afichar totjorn lo chat", + "pad.settings.colorcheck": "Colors d\u2019identificacion", + "pad.settings.linenocheck": "Num\u00e8ros de linhas", + "pad.settings.fontType": "Tipe de poli\u00e7a :", + "pad.settings.fontType.normal": "Normal", + "pad.settings.fontType.monospaced": "Monospace", + "pad.settings.globalView": "Vista d\u2019ensemble", + "pad.settings.language": "Lenga :", + "pad.importExport.import_export": "Importar\/Exportar", + "pad.importExport.import": "Cargar un t\u00e8xte o un document", + "pad.importExport.importSuccessful": "Capitat !", + "pad.importExport.export": "Exportar lo Pad actual coma :", + "pad.importExport.exporthtml": "HTML", + "pad.importExport.exportplain": "T\u00e8xte brut", + "pad.importExport.exportword": "Microsoft Word", + "pad.importExport.exportpdf": "PDF", + "pad.importExport.exportopen": "ODF (Open Document Format)", + "pad.importExport.exportdokuwiki": "DokuWiki", + "pad.importExport.abiword.innerHTML": "Pod\u00e8tz pas importar que de formats t\u00e8xte brut o html. Per de foncionalitats d'importacion mai evoluadas, installatz abiword<\/a>.", + "pad.modals.connected": "Connectat.", + "pad.modals.reconnecting": "Reconnexion cap a v\u00f2stre Pad...", + "pad.modals.forcereconnect": "For\u00e7ar la reconnexion.", + "pad.modals.userdup": "Dob\u00e8rt dins una autra fen\u00e8stra", + "pad.modals.userdup.explanation": "Sembla qu'aqueste Pad es dob\u00e8rt dins mai d'una fen\u00e8stra de v\u00f2stre navigador sus aqueste ordenador.", + "pad.modals.userdup.advice": "Se reconnectar en utilizant aquesta fen\u00e8stra.", + "pad.modals.unauth": "Pas autorizat", + "pad.modals.unauth.explanation": "V\u00f2stras permissions son estadas cambiadas al moment de l'afichatge d'aquesta pagina. Ensajatz de vos reconnectar.", + "pad.modals.looping": "Desconnectat", + "pad.modals.looping.explanation": "Av\u00e8m un probl\u00e8ma de comunicacion amb lo servidor de sincronizacion.", + "pad.modals.looping.cause": "Es possible que v\u00f2stra connexion si\u00e1 protegida per un parafu\u00f2c incompatible o un servidor proxy incompatible.", + "pad.modals.initsocketfail": "Lo servidor es introbable.", + "pad.modals.initsocketfail.explanation": "Impossible de se connectar al servidor de sincronizacion.", + "pad.modals.initsocketfail.cause": "Lo probl\u00e8ma p\u00f2t venir de v\u00f2stre navigador web o de v\u00f2stra connexion Internet.", + "pad.modals.slowcommit": "Desconnectat", + "pad.modals.slowcommit.explanation": "Lo servidor respond pas.", + "pad.modals.slowcommit.cause": "Aqueste probl\u00e8ma p\u00f2t venir d'una marrida connectivitat a la ret.", + "pad.modals.deleted": "Suprimit.", + "pad.modals.deleted.explanation": "Aqueste Pad es estat suprimit.", + "pad.modals.disconnected": "S\u00e8tz estat desconnectat.", + "pad.modals.disconnected.explanation": "La connexion al servidor a fracassat.", + "pad.modals.disconnected.cause": "Es possible que lo servidor si\u00e1 indisponible. Informatz-nos-ne se lo probl\u00e8ma persist\u00eds.", + "pad.share": "Partejar aqueste Pad", + "pad.share.readonly": "Lectura sola", + "pad.share.link": "Ligam", + "pad.share.emebdcode": "Ligam d'integrar", + "pad.chat": "Chat", + "pad.chat.title": "Dobrir lo chat associat a aqueste pad.", + "pad.chat.loadmessages": "Cargar mai de messatges.", + "timeslider.pageTitle": "Istoric dinamic de {{appTitle}}", + "timeslider.toolbar.returnbutton": "Retorn a aqueste Pad.", + "timeslider.toolbar.authors": "Autors :", + "timeslider.toolbar.authorsList": "Pas cap d'autor", + "timeslider.toolbar.exportlink.title": "Exportar", + "timeslider.exportCurrent": "Exportar la version actuala en\u00a0:", + "timeslider.version": "Version {{version}}", + "timeslider.saved": "Enregistrat lo {{day}} {{month}} {{year}}", + "timeslider.dateformat": "{{month}}\/{{day}}\/{{year}} {{hours}}:{{minutes}}:{{seconds}}", + "timeslider.month.january": "Geni\u00e8r", + "timeslider.month.february": "Febri\u00e8r", + "timeslider.month.march": "Mar\u00e7", + "timeslider.month.april": "Abril", + "timeslider.month.may": "Mai", + "timeslider.month.june": "Junh", + "timeslider.month.july": "Julhet", + "timeslider.month.august": "Agost", + "timeslider.month.september": "Setembre", + "timeslider.month.october": "Octobre", + "timeslider.month.november": "Novembre", + "timeslider.month.december": "Decembre", + "pad.savedrevs.marked": "Aquesta revision es ara marcada coma revision enregistrada", + "pad.userlist.entername": "Entratz v\u00f2stre nom", + "pad.userlist.unnamed": "sens nom", + "pad.userlist.guest": "Convidat", + "pad.userlist.deny": "Refusar", + "pad.userlist.approve": "Aprovar", + "pad.editbar.clearcolors": "Escafar las colors de paternitat dins tot lo document ?", + "pad.impexp.importbutton": "Importar ara", + "pad.impexp.importing": "Imp\u00f2rt en cors...", + "pad.impexp.confirmimport": "Importar un fichi\u00e8r espotir\u00e0 lo t\u00e8xte actual del bl\u00f2t. S\u00e8tz segur que lo vol\u00e8tz far ?", + "pad.impexp.convertFailed": "Pod\u00e8m pas importar aqueste fichi\u00e8r. Utilizatz un autre format de document o fas\u00e8tz un copiar\/pegar manual", + "pad.impexp.uploadFailed": "Lo telecargament a fracassat, reensajatz", + "pad.impexp.importfailed": "Frac\u00e0s de l'importacion", + "pad.impexp.copypaste": "Copiatz\/pegatz", + "pad.impexp.exportdisabled": "Exportar al format {{type}} es desactivat. Contactatz v\u00f2stre administrator del sist\u00e8ma per mai de detalhs." +} \ No newline at end of file diff --git a/src/locales/os.json b/src/locales/os.json index c2a289bd..4acfad7e 100644 --- a/src/locales/os.json +++ b/src/locales/os.json @@ -1,4 +1,9 @@ { + "@metadata": { + "authors": [ + "Bouron" + ] + }, "index.newPad": "\u041d\u043e\u0433", "index.createOpenPad": "\u043a\u04d5\u043d\u04d5 \u0441\u0430\u0440\u0430\u0437\/\u0431\u0430\u043a\u04d5\u043d \u043d\u043e\u0433 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0430\u0445\u04d5\u043c \u043d\u043e\u043c\u0438\u043c\u04d5:", "pad.toolbar.bold.title": "\u0411\u04d5\u0437\u0434\u0436\u044b\u043d (Ctrl-B)", @@ -44,15 +49,30 @@ "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", "pad.importExport.exportdokuwiki": "DokuWiki", + "pad.importExport.abiword.innerHTML": "\u0414\u04d5 \u0431\u043e\u043d \u0443 \u0438\u043c\u043f\u043e\u0440\u0442 \u043a\u04d5\u043d\u044b\u043d \u04d5\u0440\u043c\u04d5\u0441\u0442 \u0445\u0443\u044b\u043c\u04d5\u0442\u04d5\u0433 \u0442\u0435\u043a\u0441\u0442 \u043a\u04d5\u043d\u04d5 html \u0444\u043e\u0440\u043c\u0430\u0442\u04d5\u0439. \u041b\u04d5\u043c\u0431\u044b\u043d\u04d5\u0433 \u0438\u043c\u043f\u043e\u0440\u0442\u044b \u043c\u0438\u043d\u0438\u0443\u0434\u0436\u044b\u0442\u04d5\u043d, \u0434\u04d5 \u0445\u043e\u0440\u0437\u04d5\u0445\u04d5\u0439, \u0441\u04d5\u0432\u04d5\u0440 abiword<\/a>.", "pad.modals.connected": "\u0418\u0443\u0433\u043e\u043d\u0434.", "pad.modals.reconnecting": "\u0414\u04d5 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043c\u04d5 \u043d\u043e\u0433\u04d5\u0439 \u0438\u0443\u0433\u043e\u043d\u0434 \u0446\u04d5\u0443\u044b..", "pad.modals.forcereconnect": "\u0422\u044b\u0445\u0445\u04d5\u0439 \u0431\u0430\u0438\u0443 \u043a\u04d5\u043d\u044b\u043d", "pad.modals.userdup": "\u041d\u043e\u0433 \u0440\u0443\u0434\u0437\u044b\u043d\u0434\u0436\u044b \u0431\u0430\u043a\u04d5\u043d\u044b\u043d", "pad.modals.userdup.explanation": "\u0410\u0446\u044b \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u04d5\u0432\u04d5\u0446\u0446\u04d5\u0433\u04d5\u043d \u0430\u0446\u044b \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u044b \u0438\u0443\u04d5\u0439 \u0444\u044b\u043b\u0434\u04d5\u0440 \u0440\u0443\u0434\u0437\u044b\u043d\u0434\u0436\u044b \u0443 \u0433\u043e\u043c.", "pad.modals.userdup.advice": "\u041d\u043e\u0433\u04d5\u0439 \u0431\u0430\u0438\u0443 \u0443\u044b\u043d, \u0430\u0446\u044b \u0440\u0443\u0434\u0437\u044b\u043d\u0433\u04d5\u0439 \u0430\u0440\u0445\u0430\u0439\u044b\u043d\u044b \u0431\u04d5\u0441\u0442\u044b.", + "pad.modals.unauth": "\u041d\u04d5 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0433\u043e\u043d\u0434", "pad.modals.unauth.explanation": "\u0414\u04d5 \u0431\u0430\u0440\u0442\u04d5 \u0444\u04d5\u0438\u0432\u0442\u043e\u0439, \u0446\u0430\u043b\u044b\u043d\u043c\u04d5 \u0434\u044b \u0430\u0446\u044b \u0444\u0430\u0440\u0441 \u043a\u0430\u0441\u0442\u04d5. \u0411\u0430\u0444\u04d5\u043b\u0432\u0430\u0440 \u043d\u043e\u0433\u04d5\u0439 \u0431\u0430\u0438\u0443 \u0443\u044b\u043d.", "pad.modals.looping": "\u0425\u0438\u0446\u04d5\u043d.", + "pad.modals.looping.explanation": "\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0439\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0438\u043c\u04d5 \u0431\u0430\u0438\u0443 \u043a\u04d5\u043d\u044b\u043d\u044b \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u04d5.", + "pad.modals.looping.cause": "\u0423\u04d5\u0446\u0446\u04d5\u0433\u04d5\u043d \u0434\u044b \u0431\u0430\u0438\u0443 \u0434\u04d5 \u04d5\u043d\u04d5\u043c\u0431\u04d5\u043b\u0433\u04d5 \u0444\u0430\u0439\u0440\u0432\u043e\u043b \u043a\u04d5\u043d\u04d5 \u043f\u0440\u043e\u043a\u0441\u0438\u0439\u044b \u0443\u044b\u043b\u0442\u044b.", + "pad.modals.initsocketfail": "\u0421\u0435\u0440\u0432\u0435\u0440\u043c\u04d5 \u0431\u0430\u0438\u0443\u0433\u04d5\u043d\u04d5\u043d \u043d\u04d5\u0439.", + "pad.modals.initsocketfail.explanation": "\u041d\u04d5 \u0440\u0430\u0443\u0430\u0434\u0438\u0441 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0439\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u043c\u04d5 \u0431\u0430\u0438\u0443 \u0443\u044b\u043d.", + "pad.modals.initsocketfail.cause": "\u0410\u0439 \u0443\u04d5\u0446\u0446\u04d5\u0433\u04d5\u043d \u0434\u04d5 \u0441\u0433\u0430\u0440\u04d5\u043d \u043a\u04d5\u043d\u04d5 \u0434\u04d5 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u044b \u0442\u044b\u0445\u0445\u04d5\u0439 \u0443.", + "pad.modals.slowcommit": "\u0425\u0438\u0446\u04d5\u043d\u0433\u043e\u043d\u0434.", + "pad.modals.slowcommit.explanation": "\u0421\u0435\u0440\u0432\u0435\u0440 \u043d\u04d5 \u0434\u0437\u0443\u0430\u043f\u043f \u043a\u04d5\u043d\u044b.", + "pad.modals.slowcommit.cause": "\u0410\u0439 \u0433\u04d5\u043d\u04d5\u043d \u0438\u0441 \u0443 \u0445\u044b\u0437\u044b \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u04d5\u0439\u044b \u0442\u044b\u0445\u0445\u04d5\u0439.", "pad.modals.deleted": "\u0425\u0430\u0444\u0442.", + "pad.modals.deleted.explanation": "\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0445\u0430\u0444\u0442 \u04d5\u0440\u0446\u044b\u0434.", + "pad.modals.disconnected": "\u0414\u044b \u0445\u0438\u0446\u04d5\u043d\u0433\u043e\u043d\u0434 \u04d5\u0440\u0446\u044b\u0434\u0442\u04d5.", + "pad.modals.disconnected.explanation": "\u0421\u0435\u0440\u0432\u0435\u0440\u0438\u043c\u04d5 \u0438\u0443\u0433\u043e\u043d\u0434 \u0444\u0435\u0441\u04d5\u0444\u0442\u0438\u0441", + "pad.modals.disconnected.cause": "\u0421\u0435\u0440\u0432\u0435\u0440\u043c\u04d5 \u0433\u04d5\u043d\u04d5\u043d \u0438\u0441 \u0431\u0430\u0438\u0443\u0433\u04d5\u043d\u04d5\u043d \u043d\u04d5\u0439. \u0414\u04d5 \u0445\u043e\u0440\u0437\u04d5\u0445\u04d5\u0439, \u0444\u0435\u0445\u044a\u0443\u0441\u044b\u043d \u043d\u044b\u043d \u04d5\u0439 \u043a\u04d5\u043d, \u043a\u04d5\u0434 \u0430\u0444\u0442\u04d5 \u0434\u0430\u0440\u0434\u0434\u04d5\u0440 \u043a\u04d5\u043d\u0430.", + "pad.share": "\u0410\u0446\u044b \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0440\u0430\u0439\u0443\u0430\u0440\u044b\u043d", "pad.share.readonly": "\u04d4\u0440\u043c\u04d5\u0441\u0442 \u0444\u04d5\u0440\u0441\u044b\u043d\u04d5\u043d", "pad.share.link": "\u04d4\u0440\u0432\u0438\u0442\u04d5\u043d", "pad.share.emebdcode": "URL \u0431\u0430\u0432\u04d5\u0440\u044b\u043d", @@ -83,13 +103,15 @@ "pad.userlist.entername": "\u0414\u04d5 \u043d\u043e\u043c \u0431\u0430\u0444\u044b\u0441\u0441", "pad.userlist.unnamed": "\u04d5\u043d\u04d5\u043d\u043e\u043c", "pad.userlist.guest": "\u0423\u0430\u0437\u04d5\u0433", + "pad.userlist.deny": "\u041d\u044b\u0443\u0443\u0430\u0434\u0437\u044b\u043d", "pad.userlist.approve": "\u0421\u0431\u04d5\u043b\u0432\u044b\u0440\u0434 \u043a\u04d5\u043d\u044b\u043d", "pad.editbar.clearcolors": "\u04d4\u043d\u04d5\u0445\u044a\u04d5\u043d \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u04d5\u0439 \u0445\u044a\u04d5\u0443\u044b \u0430\u0439\u0441\u044b\u043d \u0444\u044b\u0441\u0441\u04d5\u0434\u0436\u044b\u0442\u044b \u043d\u044b\u0441\u04d5\u043d\u0442\u0442\u04d5?", "pad.impexp.importbutton": "\u0415\u043d\u044b\u0440 \u0441\u0438\u043c\u043f\u043e\u0440\u0442 \u043a\u04d5\u043d\u044b\u043d", "pad.impexp.importing": "\u0418\u043c\u043f\u043e\u0440\u0442 \u0446\u04d5\u0443\u044b...", - "@metadata": { - "authors": [ - "Bouron" - ] - } + "pad.impexp.confirmimport": "\u0424\u0430\u0439\u043b\u044b \u0438\u043c\u043f\u043e\u0440\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b \u043d\u044b\u0440\u044b \u0442\u0435\u043a\u0441\u0442 \u0431\u044b\u043d\u0442\u043e\u043d \u0444\u04d5\u0438\u0432\u0434\u0437\u04d5\u043d\u0438\u0441. \u04d4\u0446\u04d5\u0433 \u0434\u04d5 \u0444\u04d5\u043d\u0434\u044b \u0443\u044b\u0439 \u0441\u0430\u0440\u0430\u0437\u044b\u043d?", + "pad.impexp.convertFailed": "\u041c\u0430\u0445\u04d5\u043d \u043d\u04d5 \u0431\u043e\u043d \u043d\u0435 \u0441\u0441\u0438\u0441 \u0430\u0446\u044b \u0444\u0430\u0439\u043b \u0441\u0438\u043c\u043f\u043e\u0440\u0442 \u043a\u04d5\u043d\u044b\u043d. \u0414\u04d5 \u0445\u043e\u0440\u0437\u04d5\u0445\u04d5\u0439, \u0441\u043f\u0430\u0439\u0434\u0430 \u043a\u04d5\u043d \u04d5\u043d\u0434\u04d5\u0440 \u0444\u0430\u0439\u043b\u044b \u0444\u043e\u0440\u043c\u0430\u0442\u04d5\u0439, \u043a\u04d5\u043d\u04d5 \u0441\u043a\u044a\u043e\u043f\u0438 \u043a\u04d5\u043d \u04d5\u043c\u04d5 \u0431\u0430\u0442\u044b\u0441\u0441 \u0442\u0435\u043a\u0441\u0442 \u0434\u04d5\u0445\u04d5\u0434\u04d5\u0433.", + "pad.impexp.uploadFailed": "\u0411\u0430\u0432\u0433\u04d5\u043d\u044b\u043d \u043d\u04d5 \u0440\u0430\u0443\u0430\u0434, \u0434\u04d5 \u0445\u043e\u0440\u0437\u04d5\u0445\u04d5\u0439, \u0444\u04d5\u0441\u0442\u04d5\u0434\u04d5\u0440 \u0431\u0430\u0444\u04d5\u043b\u0432\u0430\u0440", + "pad.impexp.importfailed": "\u0418\u043c\u043f\u043e\u0440\u0442 \u043d\u04d5 \u0440\u0430\u0443\u0430\u0434", + "pad.impexp.copypaste": "\u0414\u04d5 \u0445\u043e\u0440\u0437\u04d5\u0445\u04d5\u0439, \u043a\u044a\u043e\u043f\u0438 \u043a\u04d5\u043d \u04d5\u043c\u04d5 \u04d5\u0432\u04d5\u0440", + "pad.impexp.exportdisabled": "{{type}} \u0444\u043e\u0440\u043c\u0430\u0442\u044b \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u0445\u0438\u0446\u04d5\u043d \u0443. \u0414\u04d5 \u0445\u043e\u0440\u0437\u04d5\u0445\u04d5\u0439, \u0431\u0430\u0434\u0437\u0443\u0440 \u0434\u04d5 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u043d \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0442\u04d5\u043c \u0444\u044b\u043b\u0434\u04d5\u0440 \u0431\u0430\u0437\u043e\u043d\u044b\u043d\u04d5\u043d." } \ No newline at end of file diff --git a/src/locales/pl.json b/src/locales/pl.json index e52f7c32..3481cafc 100644 --- a/src/locales/pl.json +++ b/src/locales/pl.json @@ -80,6 +80,7 @@ "pad.share.emebdcode": "Kod do umieszczenia", "pad.chat": "Czat", "pad.chat.title": "Otw\u00f3rz czat dla tego dokumentu.", + "pad.chat.loadmessages": "Za\u0142aduj wi\u0119cej wiadomo\u015bci", "timeslider.pageTitle": "O\u015b czasu {{appTitle}}", "timeslider.toolbar.returnbutton": "Powr\u00f3\u0107 do dokumentu", "timeslider.toolbar.authors": "Autorzy:", diff --git a/src/locales/ps.json b/src/locales/ps.json index 574fb1ad..6589c77f 100644 --- a/src/locales/ps.json +++ b/src/locales/ps.json @@ -1 +1,51 @@ -{"pad.toolbar.bold.title":"زغرد (Ctrl-B)","pad.toolbar.italic.title":"رېوند (Ctrl-I)","pad.toolbar.undo.title":"ناکړل (Ctrl-Z)","pad.toolbar.redo.title":"بياکړل (Ctrl-Y)","pad.toolbar.settings.title":"امستنې","pad.colorpicker.save":"خوندي کول","pad.colorpicker.cancel":"ناګارل","pad.loading":"برسېرېدنې کې دی...","pad.settings.myView":"زما کتنه","pad.settings.fontType":"ليکبڼې ډول:","pad.settings.fontType.normal":"نورمال","pad.settings.fontType.monospaced":"مونوسپېس","pad.settings.language":"ژبه:","pad.importExport.exporthtml":"اچ ټي ام اېل","pad.importExport.exportplain":"ساده متن","pad.importExport.exportword":"مايکروسافټ ورډ","pad.importExport.exportpdf":"پي ډي اېف","pad.importExport.exportopen":"ODF (اوپن ډاکومنټ فارمټ)","pad.modals.deleted":"ړنګ شو.","pad.share.readonly":"يوازې لوستنه","pad.share.link":"تړنه","pad.share.emebdcode":"يو آر اېل ټومبل","pad.chat":"بانډار","timeslider.toolbar.authors":"ليکوال:","timeslider.month.january":"جنوري","timeslider.month.february":"فبروري","timeslider.month.march":"مارچ","timeslider.month.april":"اپرېل","timeslider.month.may":"مۍ","timeslider.month.june":"جون","timeslider.month.july":"جولای","timeslider.month.august":"اګسټ","timeslider.month.september":"سېپتمبر","timeslider.month.october":"اکتوبر","timeslider.month.november":"نومبر","timeslider.month.december":"ډيسمبر"} \ No newline at end of file +{ + "@metadata": { + "authors": [ + "Ahmed-Najib-Biabani-Ibrahimkhel" + ] + }, + "pad.toolbar.bold.title": "\u0632\u063a\u0631\u062f (Ctrl-B)", + "pad.toolbar.italic.title": "\u0631\u06d0\u0648\u0646\u062f (Ctrl-I)", + "pad.toolbar.undo.title": "\u0646\u0627\u06a9\u0693\u0644 (Ctrl-Z)", + "pad.toolbar.redo.title": "\u0628\u064a\u0627\u06a9\u0693\u0644 (Ctrl-Y)", + "pad.toolbar.settings.title": "\u0627\u0645\u0633\u062a\u0646\u06d0", + "pad.colorpicker.save": "\u062e\u0648\u0646\u062f\u064a \u06a9\u0648\u0644", + "pad.colorpicker.cancel": "\u0646\u0627\u06ab\u0627\u0631\u0644", + "pad.loading": "\u0628\u0631\u0633\u06d0\u0631\u06d0\u062f\u0646\u06d0 \u06a9\u06d0 \u062f\u06cc...", + "pad.wrongPassword": "\u067e\u067c\u0646\u0648\u0645 \u0645\u0648 \u0633\u0645 \u0646\u0647 \u0648", + "pad.settings.myView": "\u0632\u0645\u0627 \u06a9\u062a\u0646\u0647", + "pad.settings.fontType": "\u0644\u064a\u06a9\u0628\u06bc\u06d0 \u0689\u0648\u0644:", + "pad.settings.fontType.normal": "\u0646\u0648\u0631\u0645\u0627\u0644", + "pad.settings.fontType.monospaced": "\u0645\u0648\u0646\u0648\u0633\u067e\u06d0\u0633", + "pad.settings.language": "\u0698\u0628\u0647:", + "pad.importExport.exporthtml": "\u0627\u0686 \u067c\u064a \u0627\u0645 \u0627\u06d0\u0644", + "pad.importExport.exportplain": "\u0633\u0627\u062f\u0647 \u0645\u062a\u0646", + "pad.importExport.exportword": "\u0645\u0627\u064a\u06a9\u0631\u0648\u0633\u0627\u0641\u067c \u0648\u0631\u0689", + "pad.importExport.exportpdf": "\u067e\u064a \u0689\u064a \u0627\u06d0\u0641", + "pad.importExport.exportopen": "ODF (\u0627\u0648\u067e\u0646 \u0689\u0627\u06a9\u0648\u0645\u0646\u067c \u0641\u0627\u0631\u0645\u067c)", + "pad.modals.deleted": "\u0693\u0646\u06ab \u0634\u0648.", + "pad.share.readonly": "\u064a\u0648\u0627\u0632\u06d0 \u0644\u0648\u0633\u062a\u0646\u0647", + "pad.share.link": "\u062a\u0693\u0646\u0647", + "pad.share.emebdcode": "\u064a\u0648 \u0622\u0631 \u0627\u06d0\u0644 \u067c\u0648\u0645\u0628\u0644", + "pad.chat": "\u0628\u0627\u0646\u0689\u0627\u0631", + "pad.chat.loadmessages": "\u0646\u0648\u0631 \u067e\u064a\u063a\u0627\u0645\u0648\u0646\u0647 \u0628\u0631\u0633\u06d0\u0631\u0648\u0644", + "timeslider.toolbar.authors": "\u0644\u064a\u06a9\u0648\u0627\u0644:", + "timeslider.toolbar.authorsList": "\u0628\u06d0 \u0644\u064a\u06a9\u0648\u0627\u0644\u0647", + "timeslider.month.january": "\u062c\u0646\u0648\u0631\u064a", + "timeslider.month.february": "\u0641\u0628\u0631\u0648\u0631\u064a", + "timeslider.month.march": "\u0645\u0627\u0631\u0686", + "timeslider.month.april": "\u0627\u067e\u0631\u06d0\u0644", + "timeslider.month.may": "\u0645\u06cd", + "timeslider.month.june": "\u062c\u0648\u0646", + "timeslider.month.july": "\u062c\u0648\u0644\u0627\u06cc", + "timeslider.month.august": "\u0627\u06ab\u0633\u067c", + "timeslider.month.september": "\u0633\u06d0\u067e\u062a\u0645\u0628\u0631", + "timeslider.month.october": "\u0627\u06a9\u062a\u0648\u0628\u0631", + "timeslider.month.november": "\u0646\u0648\u0645\u0628\u0631", + "timeslider.month.december": "\u0689\u064a\u0633\u0645\u0628\u0631", + "pad.userlist.entername": "\u0646\u0648\u0645 \u0645\u0648 \u0648\u0631\u06a9\u0693\u06cd", + "pad.userlist.unnamed": "\u0628\u06d0 \u0646\u0648\u0645\u0647", + "pad.userlist.guest": "\u0645\u06d0\u0644\u0645\u0647", + "pad.userlist.deny": "\u0631\u062f\u0648\u0644", + "pad.userlist.approve": "\u0645\u0646\u0644" +} \ No newline at end of file diff --git a/src/locales/pt-br.json b/src/locales/pt-br.json index a7df38fa..6562681a 100644 --- a/src/locales/pt-br.json +++ b/src/locales/pt-br.json @@ -1,4 +1,9 @@ { + "@metadata": { + "authors": [ + "Tuliouel" + ] + }, "index.newPad": "Nova Nota", "index.createOpenPad": "ou criar-abrir uma Nota com o nome:", "pad.toolbar.bold.title": "Negrito (Ctrl-B)", @@ -73,6 +78,7 @@ "pad.share.emebdcode": "Incorporar o URL", "pad.chat": "Bate-papo", "pad.chat.title": "Abrir o bate-papo desta nota.", + "pad.chat.loadmessages": "Carregar mais mensagens", "timeslider.pageTitle": "Linha do tempo de {{appTitle}}", "timeslider.toolbar.returnbutton": "Retornar para a nota", "timeslider.toolbar.authors": "Autores:", @@ -108,10 +114,5 @@ "pad.impexp.uploadFailed": "O envio falhou. Tente outra vez", "pad.impexp.importfailed": "A importa\u00e7\u00e3o falhou", "pad.impexp.copypaste": "Copie e cole", - "pad.impexp.exportdisabled": "A exposta\u00e7\u00e3o em formato {{type}} est\u00e1 desativada. Comunique-se com o administrador do sistema para detalhes.", - "@metadata": { - "authors": [ - "Tuliouel" - ] - } + "pad.impexp.exportdisabled": "A exposta\u00e7\u00e3o em formato {{type}} est\u00e1 desativada. Comunique-se com o administrador do sistema para detalhes." } \ No newline at end of file diff --git a/src/locales/ru.json b/src/locales/ru.json index 7eb34c97..1f2fbda6 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -2,6 +2,7 @@ "@metadata": { "authors": [ "Amire80", + "DCamer", "Eleferen", "Volkov" ] @@ -28,6 +29,8 @@ "pad.colorpicker.save": "\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c", "pad.colorpicker.cancel": "\u041e\u0442\u043c\u0435\u043d\u0430", "pad.loading": "\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430...", + "pad.passwordRequired": "\u0412\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430", + "pad.permissionDenied": "\u0423 \u0432\u0430\u0441 \u043d\u0435\u0442 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f", "pad.wrongPassword": "\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u043e\u043b\u044c", "pad.settings.padSettings": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430", "pad.settings.myView": "\u041c\u043e\u0439 \u0432\u0438\u0434", @@ -49,9 +52,11 @@ "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 OpenOffice)", "pad.importExport.exportdokuwiki": "DokuWiki", + "pad.importExport.abiword.innerHTML": "\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0438\u043b\u0438 HTML. \u0414\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438\u043c\u043f\u043e\u0440\u0442\u0430, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 AbiWord<\/a>.", "pad.modals.connected": "\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d.", "pad.modals.reconnecting": "\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0432\u0430\u0448\u0435\u043c\u0443 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0443", "pad.modals.forcereconnect": "\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435", + "pad.modals.userdup": "\u041e\u0442\u043a\u0440\u044b\u0442\u043e \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043e\u043a\u043d\u0435", "pad.modals.userdup.explanation": "\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043e\u0442\u043a\u0440\u044b\u0442 \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u0432 \u043e\u0434\u043d\u043e\u043c \u043e\u043a\u043d\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u043d\u0430 \u044d\u0442\u043e\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435.", "pad.modals.userdup.advice": "\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u044d\u0442\u043e\u0433\u043e \u043e\u043a\u043d\u0430.", "pad.modals.unauth": "\u041d\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d", @@ -76,22 +81,41 @@ "pad.share.emebdcode": "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044c URL", "pad.chat": "\u0427\u0430\u0442", "pad.chat.title": "\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0447\u0430\u0442 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430.", + "pad.chat.loadmessages": "\u0415\u0449\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f", "timeslider.pageTitle": "\u0412\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0448\u043a\u0430\u043b\u0430 {{appTitle}}", "timeslider.toolbar.returnbutton": "\u041a \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0443", "timeslider.toolbar.authors": "\u0410\u0432\u0442\u043e\u0440\u044b:", "timeslider.toolbar.authorsList": "\u041d\u0435\u0442 \u0430\u0432\u0442\u043e\u0440\u043e\u0432", + "timeslider.toolbar.exportlink.title": "\u042d\u043a\u0441\u043f\u043e\u0440\u0442", "timeslider.exportCurrent": "\u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043a\u0430\u043a:", "timeslider.version": "\u0412\u0435\u0440\u0441\u0438\u044f {{version}}", "timeslider.saved": "\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043e {{day}}.{{month}}.{{year}}", + "timeslider.dateformat": "{{month}}\/{{day}}\/{{year}} {{hours}}:{{minutes}}:{{seconds}}", "timeslider.month.january": "\u044f\u043d\u0432\u0430\u0440\u044c", "timeslider.month.february": "\u0444\u0435\u0432\u0440\u0430\u043b\u044c", "timeslider.month.march": "\u043c\u0430\u0440\u0442", "timeslider.month.april": "\u0430\u043f\u0440\u0435\u043b\u044c", "timeslider.month.may": "\u043c\u0430\u0439", + "timeslider.month.june": "\u0438\u044e\u043d\u044c", + "timeslider.month.july": "\u0438\u044e\u043b\u044c", + "timeslider.month.august": "\u0430\u0432\u0433\u0443\u0441\u0442", + "timeslider.month.september": "\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c", + "timeslider.month.october": "\u043e\u043a\u0442\u044f\u0431\u0440\u044c", + "timeslider.month.november": "\u043d\u043e\u044f\u0431\u0440\u044c", + "timeslider.month.december": "\u0434\u0435\u043a\u0430\u0431\u0440\u044c", + "pad.savedrevs.marked": "\u042d\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u0430 \u043a\u0430\u043a \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u0430\u044f", "pad.userlist.entername": "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0432\u0430\u0448\u0435 \u0438\u043c\u044f", + "pad.userlist.unnamed": "\u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u0439", "pad.userlist.guest": "\u0413\u043e\u0441\u0442\u044c", + "pad.userlist.deny": "\u041e\u0442\u043a\u043b\u043e\u043d\u0438\u0442\u044c", + "pad.userlist.approve": "\u0423\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c", + "pad.editbar.clearcolors": "\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0441\u043a\u0438\u0435 \u0446\u0432\u0435\u0442\u0430 \u0432\u043e \u0432\u0441\u0435\u043c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0435?", "pad.impexp.importbutton": "\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441", "pad.impexp.importing": "\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u2026", + "pad.impexp.confirmimport": "\u0418\u043c\u043f\u043e\u0440\u0442 \u0444\u0430\u0439\u043b\u0430 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0448\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0442\u0435\u043a\u0441\u0442. \u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c?", + "pad.impexp.convertFailed": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u0438\u043b\u0438 \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044e", "pad.impexp.uploadFailed": "\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u0430\u0441\u044c, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0435\u0449\u0451 \u0440\u0430\u0437", - "pad.impexp.importfailed": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438" + "pad.impexp.importfailed": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438", + "pad.impexp.copypaste": "\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435", + "pad.impexp.exportdisabled": "\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 {{type}} \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d. \u0414\u043b\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c \u043a \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u043c\u0443 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0443." } \ No newline at end of file diff --git a/src/locales/sl.json b/src/locales/sl.json index 9cec99f7..c7cffa6f 100644 --- a/src/locales/sl.json +++ b/src/locales/sl.json @@ -1,4 +1,9 @@ { + "@metadata": { + "authors": [ + "Mateju" + ] + }, "index.newPad": "Nov dokument", "index.createOpenPad": "ali pa odpri dokument z imenom:", "pad.toolbar.bold.title": "Krepko (Ctrl-B)", @@ -73,6 +78,7 @@ "pad.share.emebdcode": "Vstavi naslov URL", "pad.chat": "Klepet", "pad.chat.title": "Odpri klepetalno okno dokumenta.", + "pad.chat.loadmessages": "Nalo\u017ei ve\u010d sporo\u010dil", "timeslider.pageTitle": "Zgodovina dokumenta {{appTitle}}", "timeslider.toolbar.returnbutton": "Vrni se na dokument", "timeslider.toolbar.authors": "Autorji:", @@ -108,10 +114,5 @@ "pad.impexp.uploadFailed": "Nalaganje je spodletelo, poskusite znova.", "pad.impexp.importfailed": "Uvoz je spodletel.", "pad.impexp.copypaste": "Vsebino kopirajte in prilepite.", - "pad.impexp.exportdisabled": "Izvoz v zapis {{type}} je onemogo\u010den. Za ve\u010d podrobnosti stopite v stik s skrbnikom.", - "@metadata": { - "authors": [ - "Mateju" - ] - } + "pad.impexp.exportdisabled": "Izvoz v zapis {{type}} je onemogo\u010den. Za ve\u010d podrobnosti stopite v stik s skrbnikom." } \ No newline at end of file diff --git a/src/locales/sv.json b/src/locales/sv.json index 54dc2513..fa493bfe 100644 --- a/src/locales/sv.json +++ b/src/locales/sv.json @@ -78,6 +78,7 @@ "pad.share.emebdcode": "B\u00e4dda in URL", "pad.chat": "Chatt", "pad.chat.title": "\u00d6ppna chatten f\u00f6r detta block.", + "pad.chat.loadmessages": "L\u00e4s in fler meddelanden", "timeslider.pageTitle": "Tidsreglage f\u00f6r {{appTitle}}", "timeslider.toolbar.returnbutton": "\u00c5terv\u00e4nd till blocket", "timeslider.toolbar.authors": "F\u00f6rfattare:", diff --git a/src/locales/uk.json b/src/locales/uk.json index af035c65..ae6cbbb6 100644 --- a/src/locales/uk.json +++ b/src/locales/uk.json @@ -80,6 +80,7 @@ "pad.share.emebdcode": "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u0438 URL", "pad.chat": "\u0427\u0430\u0442", "pad.chat.title": "\u0412\u0456\u0434\u043a\u0440\u0438\u0442\u0438 \u0447\u0430\u0442 \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0443.", + "pad.chat.loadmessages": "\u0417\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0438\u0442\u0438 \u0431\u0456\u043b\u044c\u0448\u0435 \u043f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u0435\u043d\u044c", "timeslider.pageTitle": "\u0427\u0430\u0441\u043e\u0432\u0430 \u0448\u043a\u0430\u043b\u0430 {{appTitle}}", "timeslider.toolbar.returnbutton": "\u041f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0438\u0441\u044c \u0434\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0443", "timeslider.toolbar.authors": "\u0410\u0432\u0442\u043e\u0440\u0438:", diff --git a/src/locales/zh-hant.json b/src/locales/zh-hant.json index c91e2fe3..6ee1e377 100644 --- a/src/locales/zh-hant.json +++ b/src/locales/zh-hant.json @@ -78,6 +78,7 @@ "pad.share.emebdcode": "\u5d4c\u5165\u7db2\u5740", "pad.chat": "\u804a\u5929", "pad.chat.title": "\u6253\u958b\u6b64pad\u7684\u804a\u5929\u3002", + "pad.chat.loadmessages": "\u8f09\u5165\u66f4\u591a\u8a0a\u606f", "timeslider.pageTitle": "{{appTitle}}\u6642\u9593\u8ef8", "timeslider.toolbar.returnbutton": "\u8fd4\u56de\u5230pad", "timeslider.toolbar.authors": "\u4f5c\u8005\uff1a", diff --git a/src/node/db/API.js b/src/node/db/API.js index 9cad415d..f99a43af 100644 --- a/src/node/db/API.js +++ b/src/node/db/API.js @@ -30,6 +30,7 @@ var async = require("async"); var exportHtml = require("../utils/ExportHtml"); var importHtml = require("../utils/ImportHtml"); var cleanText = require("./Pad").cleanText; +var PadDiff = require("../utils/padDiff"); /**********************/ /**GROUP FUNCTIONS*****/ @@ -277,6 +278,77 @@ exports.setHTML = function(padID, html, callback) }); } +/******************/ +/**CHAT FUNCTIONS */ +/******************/ + +/** +getChatHistory(padId, start, end), returns a part of or the whole chat-history of this pad + +Example returns: + +{"code":0,"message":"ok","data":{"messages":[{"text":"foo","userId":"a.foo","time":1359199533759,"userName":"test"}, + {"text":"bar","userId":"a.foo","time":1359199534622,"userName":"test"}]}} + +{code: 1, message:"start is higher or equal to the current chatHead", data: null} + +{code: 1, message:"padID does not exist", data: null} +*/ +exports.getChatHistory = function(padID, start, end, callback) +{ + if(start && end) + { + if(start < 0) + { + callback(new customError("start is below zero","apierror")); + return; + } + if(end < 0) + { + callback(new customError("end is below zero","apierror")); + return; + } + if(start > end) + { + callback(new customError("start is higher than end","apierror")); + return; + } + } + + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + var chatHead = pad.chatHead; + + // fall back to getting the whole chat-history if a parameter is missing + if(!start || !end) + { + start = 0; + end = pad.chatHead - 1; + } + + if(start >= chatHead) + { + callback(new customError("start is higher or equal to the current chatHead","apierror")); + return; + } + if(end >= chatHead) + { + callback(new customError("end is higher or equal to the current chatHead","apierror")); + return; + } + + // the the whole message-log and return it to the client + pad.getChatMessages(start, end, + function(err, msgs) + { + if(ERR(err, callback)) return; + callback(null, {messages: msgs}); + }); + }); +} + /*****************/ /**PAD FUNCTIONS */ /*****************/ @@ -567,6 +639,103 @@ exports.checkToken = function(callback) callback(); } +/** +getChatHead(padID) returns the chatHead (last number of the last chat-message) of the pad + +Example returns: + +{code: 0, message:"ok", data: {chatHead: 42}} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.getChatHead = function(padID, callback) +{ + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + callback(null, {chatHead: pad.chatHead}); + }); +} + +/** +createDiffHTML(padID, startRev, endRev) returns an object of diffs from 2 points in a pad + +Example returns: + +{"code":0,"message":"ok","data":{"html":"Welcome to Etherpad Lite!

This pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!

Get involved with Etherpad at
http://etherpad.org
aw

","authors":["a.HKIv23mEbachFYfH",""]}} +{"code":4,"message":"no or wrong API Key","data":null} +*/ +exports.createDiffHTML = function(padID, startRev, endRev, callback){ + //check if rev is a number + if(startRev !== undefined && typeof startRev != "number") + { + //try to parse the number + if(!isNaN(parseInt(startRev))) + { + startRev = parseInt(startRev, 10); + } + else + { + callback({stop: "startRev is not a number"}); + return; + } + } + + //check if rev is a number + if(endRev !== undefined && typeof endRev != "number") + { + //try to parse the number + if(!isNaN(parseInt(endRev))) + { + endRev = parseInt(endRev, 10); + } + else + { + callback({stop: "endRev is not a number"}); + return; + } + } + + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(err){ + return callback(err); + } + + try { + var padDiff = new PadDiff(pad, startRev, endRev); + } catch(e) { + return callback({stop:e.message}); + } + var html, authors; + + async.series([ + function(callback){ + padDiff.getHtml(function(err, _html){ + if(err){ + return callback(err); + } + + html = _html; + callback(); + }); + }, + function(callback){ + padDiff.getAuthors(function(err, _authors){ + if(err){ + return callback(err); + } + + authors = _authors; + callback(); + }); + } + ], function(err){ + callback(err, {html: html, authors: authors}) + }); + }); +} /******************************/ /** INTERNAL HELPER FUNCTIONS */ diff --git a/src/node/db/AuthorManager.js b/src/node/db/AuthorManager.js index 28b2dd91..667e0605 100644 --- a/src/node/db/AuthorManager.js +++ b/src/node/db/AuthorManager.js @@ -24,6 +24,10 @@ var db = require("./DB").db; var async = require("async"); var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString; +exports.getColorPalette = function(){ + return ["#ffc7c7", "#fff1c7", "#e3ffc7", "#c7ffd5", "#c7ffff", "#c7d5ff", "#e3c7ff", "#ffc7f1", "#ff8f8f", "#ffe38f", "#c7ff8f", "#8fffab", "#8fffff", "#8fabff", "#c78fff", "#ff8fe3", "#d97979", "#d9c179", "#a9d979", "#79d991", "#79d9d9", "#7991d9", "#a979d9", "#d979c1", "#d9a9a9", "#d9cda9", "#c1d9a9", "#a9d9b5", "#a9d9d9", "#a9b5d9", "#c1a9d9", "#d9a9cd", "#4c9c82", "#12d1ad", "#2d8e80", "#7485c3", "#a091c7", "#3185ab", "#6818b4", "#e6e76d", "#a42c64", "#f386e5", "#4ecc0c", "#c0c236", "#693224", "#b5de6a", "#9b88fd", "#358f9b", "#496d2f", "#e267fe", "#d23056", "#1a1a64", "#5aa335", "#d722bb", "#86dc6c", "#b5a714", "#955b6a", "#9f2985", "#4b81c8", "#3d6a5b", "#434e16", "#d16084", "#af6a0e", "#8c8bd8"]; +}; + /** * Checks if the author exists */ diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index da1ce9e1..4701e82a 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -213,6 +213,48 @@ Pad.prototype.getInternalRevisionAText = function getInternalRevisionAText(targe }); }; +Pad.prototype.getRevision = function getRevisionChangeset(revNum, callback) { + db.get("pad:"+this.id+":revs:"+revNum, callback); +}; + +Pad.prototype.getAllAuthorColors = function getAllAuthorColors(callback){ + var authors = this.getAllAuthors(); + var returnTable = {}; + var colorPalette = authorManager.getColorPalette(); + + async.forEach(authors, function(author, callback){ + authorManager.getAuthorColorId(author, function(err, colorId){ + if(err){ + return callback(err); + } + //colorId might be a hex color or an number out of the palette + returnTable[author]=colorPalette[colorId] || colorId; + + callback(); + }); + }, function(err){ + callback(err, returnTable); + }); +}; + +Pad.prototype.getValidRevisionRange = function getValidRevisionRange(startRev, endRev) { + startRev = parseInt(startRev, 10); + var head = this.getHeadRevisionNumber(); + endRev = endRev ? parseInt(endRev, 10) : head; + if(isNaN(startRev) || startRev < 0 || startRev > head) { + startRev = null; + } + if(isNaN(endRev) || endRev < startRev) { + endRev = null; + } else if(endRev > head) { + endRev = head; + } + if(startRev !== null && endRev !== null) { + return { startRev: startRev , endRev: endRev } + } + return null; +}; + Pad.prototype.getKeyRevisionNumber = function getKeyRevisionNumber(revNum) { return Math.floor(revNum / 100) * 100; }; diff --git a/src/node/handler/APIHandler.js b/src/node/handler/APIHandler.js index ae93e933..9f86277a 100644 --- a/src/node/handler/APIHandler.js +++ b/src/node/handler/APIHandler.js @@ -174,6 +174,46 @@ var version = , "listAllGroups" : [] , "checkToken" : [] } +, "1.2.7": + { "createGroup" : [] + , "createGroupIfNotExistsFor" : ["groupMapper"] + , "deleteGroup" : ["groupID"] + , "listPads" : ["groupID"] + , "listAllPads" : [] + , "createDiffHTML" : ["padID", "startRev", "endRev"] + , "createPad" : ["padID", "text"] + , "createGroupPad" : ["groupID", "padName", "text"] + , "createAuthor" : ["name"] + , "createAuthorIfNotExistsFor": ["authorMapper" , "name"] + , "listPadsOfAuthor" : ["authorID"] + , "createSession" : ["groupID", "authorID", "validUntil"] + , "deleteSession" : ["sessionID"] + , "getSessionInfo" : ["sessionID"] + , "listSessionsOfGroup" : ["groupID"] + , "listSessionsOfAuthor" : ["authorID"] + , "getText" : ["padID", "rev"] + , "setText" : ["padID", "text"] + , "getHTML" : ["padID", "rev"] + , "setHTML" : ["padID", "html"] + , "getRevisionsCount" : ["padID"] + , "getLastEdited" : ["padID"] + , "deletePad" : ["padID"] + , "getReadOnlyID" : ["padID"] + , "setPublicStatus" : ["padID", "publicStatus"] + , "getPublicStatus" : ["padID"] + , "setPassword" : ["padID", "password"] + , "isPasswordProtected" : ["padID"] + , "listAuthorsOfPad" : ["padID"] + , "padUsersCount" : ["padID"] + , "getAuthorName" : ["authorID"] + , "padUsers" : ["padID"] + , "sendClientsMessage" : ["padID", "msg"] + , "listAllGroups" : [] + , "checkToken" : [] + , "getChatHistory" : ["padID"] + , "getChatHistory" : ["padID", "start", "end"] + , "getChatHead" : ["padID"] + } }; /** diff --git a/src/node/handler/ImportHandler.js b/src/node/handler/ImportHandler.js index 5ec07390..ac856a60 100644 --- a/src/node/handler/ImportHandler.js +++ b/src/node/handler/ImportHandler.js @@ -176,7 +176,7 @@ exports.doImport = function(req, res, padId) ERR(err); //close the connection - res.send("", 200); + res.send("", 200); }); } diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 434c25ad..6781cd88 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -210,6 +210,7 @@ exports.handleMessage = function(client, message) } else if (message.data.type == "SAVE_REVISION") { handleSaveRevisionMessage(client, message); } else if (message.data.type == "CLIENT_MESSAGE" && + message.data.payload != null && message.data.payload.type == "suggestUserName") { handleSuggestUserName(client, message); } else { @@ -473,6 +474,11 @@ function handleSuggestUserName(client, message) function handleUserInfoUpdate(client, message) { //check if all ok + if(message.data.userInfo == null) + { + messageLogger.warn("Dropped message, USERINFO_UPDATE Message has no userInfo!"); + return; + } if(message.data.userInfo.colorId == null) { messageLogger.warn("Dropped message, USERINFO_UPDATE Message has no colorId!"); @@ -1028,7 +1034,7 @@ function handleClientReady(client, message) "globalPadId": message.padId, "time": currentTime, }, - "colorPalette": ["#ffc7c7", "#fff1c7", "#e3ffc7", "#c7ffd5", "#c7ffff", "#c7d5ff", "#e3c7ff", "#ffc7f1", "#ff8f8f", "#ffe38f", "#c7ff8f", "#8fffab", "#8fffff", "#8fabff", "#c78fff", "#ff8fe3", "#d97979", "#d9c179", "#a9d979", "#79d991", "#79d9d9", "#7991d9", "#a979d9", "#d979c1", "#d9a9a9", "#d9cda9", "#c1d9a9", "#a9d9b5", "#a9d9d9", "#a9b5d9", "#c1a9d9", "#d9a9cd", "#4c9c82", "#12d1ad", "#2d8e80", "#7485c3", "#a091c7", "#3185ab", "#6818b4", "#e6e76d", "#a42c64", "#f386e5", "#4ecc0c", "#c0c236", "#693224", "#b5de6a", "#9b88fd", "#358f9b", "#496d2f", "#e267fe", "#d23056", "#1a1a64", "#5aa335", "#d722bb", "#86dc6c", "#b5a714", "#955b6a", "#9f2985", "#4b81c8", "#3d6a5b", "#434e16", "#d16084", "#af6a0e", "#8c8bd8"], + "colorPalette": authorManager.getColorPalette(), "clientIp": "127.0.0.1", "userIsGuest": true, "userColor": authorColorId, @@ -1536,6 +1542,7 @@ exports.padUsers = function (padID, callback) { } var aid = sessioninfos[ix].author; authorManager.getAuthor( aid, function ( err, author ) { + author.id = aid; authors.push( author ); if ( authors.length === pad2sessions[padID].length ) { callback(null, {padUsers: authors}); diff --git a/src/node/hooks/express/adminplugins.js b/src/node/hooks/express/adminplugins.js index 97a0d602..7e221cf1 100644 --- a/src/node/hooks/express/adminplugins.js +++ b/src/node/hooks/express/adminplugins.js @@ -2,6 +2,9 @@ var path = require('path'); var eejs = require('ep_etherpad-lite/node/eejs'); var installer = require('ep_etherpad-lite/static/js/pluginfw/installer'); var plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins'); +var _ = require('underscore'); +var semver = require('semver'); +var async = require('async'); exports.expressCreateServer = function (hook_name, args, cb) { args.app.get('/admin/plugins', function(req, res) { @@ -25,8 +28,26 @@ exports.socketio = function (hook_name, args, cb) { if (!socket.handshake.session.user || !socket.handshake.session.user.is_admin) return; socket.on("load", function (query) { + // send currently installed plugins socket.emit("installed-results", {results: plugins.plugins}); + socket.emit("progress", {progress:1}); }); + + socket.on("checkUpdates", function() { + socket.emit("progress", {progress:0, message:'Checking for plugin updates...'}); + // Check plugins for updates + installer.search({offset: 0, pattern: '', limit: 500}, /*useCache:*/true, function(data) { // hacky + if (!data.results) return; + var updatable = _(plugins.plugins).keys().filter(function(plugin) { + if(!data.results[plugin]) return false; + var latestVersion = data.results[plugin]['dist-tags'].latest + var currentVersion = plugins.plugins[plugin].package.version + return semver.gt(latestVersion, currentVersion) + }); + socket.emit("updatable", {updatable: updatable}); + socket.emit("progress", {progress:1}); + }); + }) socket.on("search", function (query) { socket.emit("progress", {progress:0, message:'Fetching results...'}); diff --git a/src/node/utils/ExportHtml.js b/src/node/utils/ExportHtml.js index 35403013..06919488 100644 --- a/src/node/utils/ExportHtml.js +++ b/src/node/utils/ExportHtml.js @@ -1,12 +1,12 @@ /** * Copyright 2009 Google Inc. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS-IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -91,8 +91,9 @@ function getPadHTML(pad, revNum, callback) } exports.getPadHTML = getPadHTML; +exports.getHTMLFromAtext = getHTMLFromAtext; -function getHTMLFromAtext(pad, atext) +function getHTMLFromAtext(pad, atext, authorColors) { var apool = pad.apool(); var textLines = atext.text.slice(0, -1).split('\n'); @@ -101,6 +102,42 @@ function getHTMLFromAtext(pad, atext) var tags = ['h1', 'h2', 'strong', 'em', 'u', 's']; var props = ['heading1', 'heading2', 'bold', 'italic', 'underline', 'strikethrough']; var anumMap = {}; + var css = ""; + + var stripDotFromAuthorID = function(id){ + return id.replace(/\./g,'_'); + }; + + if(authorColors){ + css+=""; + } props.forEach(function (propName, i) { @@ -125,22 +162,53 @@ function getHTMLFromAtext(pad, atext) // Just bold Bold and italics Just italics var taker = Changeset.stringIterator(text); var assem = Changeset.stringAssembler(); - var openTags = []; + + function getSpanClassFor(i){ + //return if author colors are disabled + if (!authorColors) return false; + + var property = props[i]; + + if(property.substr(0,6) === "author"){ + return stripDotFromAuthorID(property); + } + + if(property === "removed"){ + return "removed"; + } + + return false; + } + function emitOpenTag(i) { openTags.unshift(i); - assem.append('<'); - assem.append(tags[i]); - assem.append('>'); + var spanClass = getSpanClassFor(i); + + if(spanClass){ + assem.append(''); + } else { + assem.append('<'); + assem.append(tags[i]); + assem.append('>'); + } } function emitCloseTag(i) { openTags.shift(); - assem.append(''); + var spanClass = getSpanClassFor(i); + + if(spanClass){ + assem.append(''); + } else { + assem.append(''); + } } function orderdCloseTags(tags2close) @@ -303,7 +371,7 @@ function getHTMLFromAtext(pad, atext) return _processSpaces(assem.toString()); } // end getLineHTML - var pieces = []; + var pieces = [css]; // Need to deal with constraints imposed on HTML lists; can // only gain one level of nesting at once, can't change type diff --git a/src/node/utils/padDiff.js b/src/node/utils/padDiff.js new file mode 100644 index 00000000..1b3cf58f --- /dev/null +++ b/src/node/utils/padDiff.js @@ -0,0 +1,554 @@ +var Changeset = require("../../static/js/Changeset"); +var async = require("async"); +var exportHtml = require('./ExportHtml'); + +function PadDiff (pad, fromRev, toRev){ + //check parameters + if(!pad || !pad.id || !pad.atext || !pad.pool) + { + throw new Error('Invalid pad'); + } + + var range = pad.getValidRevisionRange(fromRev, toRev); + if(!range) { throw new Error('Invalid revision range.' + + ' startRev: ' + fromRev + + ' endRev: ' + toRev); } + + this._pad = pad; + this._fromRev = range.startRev; + this._toRev = range.endRev; + this._html = null; + this._authors = []; +} + +PadDiff.prototype._isClearAuthorship = function(changeset){ + //unpack + var unpacked = Changeset.unpack(changeset); + + //check if there is nothing in the charBank + if(unpacked.charBank !== "") + return false; + + //check if oldLength == newLength + if(unpacked.oldLen !== unpacked.newLen) + return false; + + //lets iterator over the operators + var iterator = Changeset.opIterator(unpacked.ops); + + //get the first operator, this should be a clear operator + var clearOperator = iterator.next(); + + //check if there is only one operator + if(iterator.hasNext() === true) + return false; + + //check if this operator doesn't change text + if(clearOperator.opcode !== "=") + return false; + + //check that this operator applys to the complete text + //if the text ends with a new line, its exactly one character less, else it has the same length + if(clearOperator.chars !== unpacked.oldLen-1 && clearOperator.chars !== unpacked.oldLen) + return false; + + var attributes = []; + Changeset.eachAttribNumber(changeset, function(attrNum){ + attributes.push(attrNum); + }); + + //check that this changeset uses only one attribute + if(attributes.length !== 1) + return false; + + var appliedAttribute = this._pad.pool.getAttrib(attributes[0]); + + //check if the applied attribute is an anonymous author attribute + if(appliedAttribute[0] !== "author" || appliedAttribute[1] !== "") + return false; + + return true; +} + +PadDiff.prototype._createClearAuthorship = function(rev, callback){ + var self = this; + this._pad.getInternalRevisionAText(rev, function(err, atext){ + if(err){ + return callback(err); + } + + //build clearAuthorship changeset + var builder = Changeset.builder(atext.text.length); + builder.keepText(atext.text, [['author','']], self._pad.pool); + var changeset = builder.toString(); + + callback(null, changeset); + }); +} + +PadDiff.prototype._createClearStartAtext = function(rev, callback){ + var self = this; + + //get the atext of this revision + this._pad.getInternalRevisionAText(rev, function(err, atext){ + if(err){ + return callback(err); + } + + //create the clearAuthorship changeset + self._createClearAuthorship(rev, function(err, changeset){ + if(err){ + return callback(err); + } + + //apply the clearAuthorship changeset + var newAText = Changeset.applyToAText(changeset, atext, self._pad.pool); + + callback(null, newAText); + }); + }); +} + +PadDiff.prototype._getChangesetsInBulk = function(startRev, count, callback) { + var self = this; + + //find out which revisions we need + var revisions = []; + for(var i=startRev;i<(startRev+count) && i<=this._pad.head;i++){ + revisions.push(i); + } + + var changesets = [], authors = []; + + //get all needed revisions + async.forEach(revisions, function(rev, callback){ + self._pad.getRevision(rev, function(err, revision){ + if(err){ + return callback(err) + } + + var arrayNum = rev-startRev; + + changesets[arrayNum] = revision.changeset; + authors[arrayNum] = revision.meta.author; + + callback(); + }); + }, function(err){ + callback(err, changesets, authors); + }); +} + +PadDiff.prototype._addAuthors = function(authors) { + var self = this; + //add to array if not in the array + authors.forEach(function(author){ + if(self._authors.indexOf(author) == -1){ + self._authors.push(author); + } + }); +} + +PadDiff.prototype._createDiffAtext = function(callback) { + var self = this; + var bulkSize = 100; + + //get the cleaned startAText + self._createClearStartAtext(self._fromRev, function(err, atext){ + if(err) { return callback(err); } + + var superChangeset = null; + + var rev = self._fromRev + 1; + + //async while loop + async.whilst( + //loop condition + function () { return rev <= self._toRev; }, + + //loop body + function (callback) { + //get the bulk + self._getChangesetsInBulk(rev,bulkSize,function(err, changesets, authors){ + var addedAuthors = []; + + //run trough all changesets + for(var i=0;i= curChar) { + curLineNextOp.chars -= (curChar - indexIntoLine); + done = true; + } else { + indexIntoLine += curLineNextOp.chars; + } + } + } + + while (numChars > 0) { + if ((!curLineNextOp.chars) && (!curLineOpIter.hasNext())) { + curLine++; + curChar = 0; + curLineOpIterLine = curLine; + curLineNextOp.chars = 0; + curLineOpIter = Changeset.opIterator(alines_get(curLine)); + } + if (!curLineNextOp.chars) { + curLineOpIter.next(curLineNextOp); + } + var charsToUse = Math.min(numChars, curLineNextOp.chars); + func(charsToUse, curLineNextOp.attribs, charsToUse == curLineNextOp.chars && curLineNextOp.lines > 0); + numChars -= charsToUse; + curLineNextOp.chars -= charsToUse; + curChar += charsToUse; + } + + if ((!curLineNextOp.chars) && (!curLineOpIter.hasNext())) { + curLine++; + curChar = 0; + } + } + + function skip(N, L) { + if (L) { + curLine += L; + curChar = 0; + } else { + if (curLineOpIter && curLineOpIterLine == curLine) { + consumeAttribRuns(N, function () {}); + } else { + curChar += N; + } + } + } + + function nextText(numChars) { + var len = 0; + var assem = Changeset.stringAssembler(); + var firstString = lines_get(curLine).substring(curChar); + len += firstString.length; + assem.append(firstString); + + var lineNum = curLine + 1; + while (len < numChars) { + var nextString = lines_get(lineNum); + len += nextString.length; + assem.append(nextString); + lineNum++; + } + + return assem.toString().substring(0, numChars); + } + + function cachedStrFunc(func) { + var cache = {}; + return function (s) { + if (!cache[s]) { + cache[s] = func(s); + } + return cache[s]; + }; + } + + var attribKeys = []; + var attribValues = []; + + //iterate over all operators of this changeset + while (csIter.hasNext()) { + var csOp = csIter.next(); + + if (csOp.opcode == '=') { + var textBank = nextText(csOp.chars); + + // decide if this equal operator is an attribution change or not. We can see this by checkinf if attribs is set. + // If the text this operator applies to is only a star, than this is a false positive and should be ignored + if (csOp.attribs && textBank != "*") { + var deletedAttrib = apool.putAttrib(["removed", true]); + var authorAttrib = apool.putAttrib(["author", ""]);; + + attribKeys.length = 0; + attribValues.length = 0; + Changeset.eachAttribNumber(csOp.attribs, function (n) { + attribKeys.push(apool.getAttribKey(n)); + attribValues.push(apool.getAttribValue(n)); + + if(apool.getAttribKey(n) === "author"){ + authorAttrib = n; + }; + }); + + var undoBackToAttribs = cachedStrFunc(function (attribs) { + var backAttribs = []; + for (var i = 0; i < attribKeys.length; i++) { + var appliedKey = attribKeys[i]; + var appliedValue = attribValues[i]; + var oldValue = Changeset.attribsAttributeValue(attribs, appliedKey, apool); + if (appliedValue != oldValue) { + backAttribs.push([appliedKey, oldValue]); + } + } + return Changeset.makeAttribsString('=', backAttribs, apool); + }); + + var oldAttribsAddition = "*" + Changeset.numToString(deletedAttrib) + "*" + Changeset.numToString(authorAttrib); + + var textLeftToProcess = textBank; + + while(textLeftToProcess.length > 0){ + //process till the next line break or process only one line break + var lengthToProcess = textLeftToProcess.indexOf("\n"); + var lineBreak = false; + switch(lengthToProcess){ + case -1: + lengthToProcess=textLeftToProcess.length; + break; + case 0: + lineBreak = true; + lengthToProcess=1; + break; + } + + //get the text we want to procceed in this step + var processText = textLeftToProcess.substr(0, lengthToProcess); + textLeftToProcess = textLeftToProcess.substr(lengthToProcess); + + if(lineBreak){ + builder.keep(1, 1); //just skip linebreaks, don't do a insert + keep for a linebreak + + //consume the attributes of this linebreak + consumeAttribRuns(1, function(){}); + } else { + //add the old text via an insert, but add a deletion attribute + the author attribute of the author who deleted it + var textBankIndex = 0; + consumeAttribRuns(lengthToProcess, function (len, attribs, endsLine) { + //get the old attributes back + var attribs = (undoBackToAttribs(attribs) || "") + oldAttribsAddition; + + builder.insert(processText.substr(textBankIndex, len), attribs); + textBankIndex += len; + }); + + builder.keep(lengthToProcess, 0); + } + } + } else { + skip(csOp.chars, csOp.lines); + builder.keep(csOp.chars, csOp.lines); + } + } else if (csOp.opcode == '+') { + builder.keep(csOp.chars, csOp.lines); + } else if (csOp.opcode == '-') { + var textBank = nextText(csOp.chars); + var textBankIndex = 0; + + consumeAttribRuns(csOp.chars, function (len, attribs, endsLine) { + builder.insert(textBank.substr(textBankIndex, len), attribs + csOp.attribs); + textBankIndex += len; + }); + } + } + + return Changeset.checkRep(builder.toString()); +}; + +//export the constructor +module.exports = PadDiff; diff --git a/src/node/utils/tar.json b/src/node/utils/tar.json index 080da442..b010f851 100644 --- a/src/node/utils/tar.json +++ b/src/node/utils/tar.json @@ -14,6 +14,7 @@ , "pad_savedrevs.js" , "pad_connectionstatus.js" , "chat.js" + , "gritter.js" , "$tinycon/tinycon.js" , "excanvas.js" , "farbtastic.js" diff --git a/src/static/css/admin.css b/src/static/css/admin.css index b91850a6..3a729151 100644 --- a/src/static/css/admin.css +++ b/src/static/css/admin.css @@ -7,17 +7,52 @@ body { background: -moz-radial-gradient(circle,#aaa,#eee 60%) center fixed; background: -ms-radial-gradient(circle,#aaa,#eee 60%) center fixed; background: -o-radial-gradient(circle,#aaa,#eee 60%) center fixed; - border-top: 8px solid rgba(51,51,51,.8); } -#wrapper { - margin-top: 160px; + +#topborder { + border-top: 8px solid rgba(51, 51, 51, 0.8); + position: fixed; + top: 0px; + width: 100%; +} + +div.menu { + background: none repeat scroll 0% 0% rgba(255, 255, 255, 0.75); + box-shadow: 0px -4px 4px rgba(0, 0, 0, 0.3); + display: block; + float: left; + height: 100%; + padding: 15px; + position: fixed; + width: 220px; +} + +div.menu li { + list-style: none; + margin-left: 3px; + line-height: 1.6 +} + +div.innerwrapper { + display: block; + float: right; + opacity: 0.9; padding: 15px; - background: #fff; - opacity: .9; - box-shadow: 0px 1px 8px rgba(0,0,0,0.3); - max-width: 700px; - margin: auto; + max-width: 860px; border-radius: 0 0 7px 7px; + margin-left:250px; + min-width:400px; +} + +#wrapper { + background: none repeat scroll 0px 0px #FFFFFF; + box-shadow: 0px 1px 8px rgba(0, 0, 0, 0.3); + margin: auto; + max-width: 1150px; + min-height: 100%; + overflow: auto; + padding-left: 15px; + opacity: .9; } h1 { font-size: 29px; @@ -49,13 +84,10 @@ input[type="button"] { padding: 4px 6px; margin: 0; } -input[type="button"].do-install, input[type="button"].do-uninstall { +table input[type="button"] { float: right; width: 100px; } -input[type="button"]#do-search { - display: block; -} input[type="text"] { border-radius: 3px; box-sizing: border-box; @@ -84,41 +116,9 @@ td, th { .template { display: none; } -.dialog { - display: none; +#progress { position: absolute; - left: 50%; - top: 50%; - width: 700px; - height: 500px; - margin-left: -350px; - margin-top: -250px; - border: 3px solid #999; - background: #eee; -} -.dialog .title { - margin: 0; - padding: 2px; - border-bottom: 3px solid #999; - font-size: 24px; - line-height: 24px; - height: 24px; - overflow: hidden; -} -.dialog .title .close { - float: right; - padding: 1px 10px; -} -.dialog .history { - background: #222; - color: #eee; - position: absolute; - top: 41px; - bottom: 10px; - left: 10px; - right: 10px; - padding: 2px; - overflow: auto; + bottom: 50px; } .settings { margin-top:10px; @@ -128,3 +128,13 @@ td, th { #response{ display:inline; } + +a:link, a:visited, a:hover, a:focus { + color: #333333; + text-decoration: none; + border-bottom: #333333 1px dotted; +} + +a:focus, a:hover { + border-bottom: #333333 1px solid; +} diff --git a/src/static/css/pad.css b/src/static/css/pad.css index bbbadbc1..6034b5ed 100644 --- a/src/static/css/pad.css +++ b/src/static/css/pad.css @@ -925,3 +925,95 @@ input[type=checkbox] { #wrongPassword{ display:none; } + +/* gritter stuff */ +#gritter-notice-wrapper { + position:fixed; + top:20px; + right:20px; + width:301px; + z-index:9999; +} +#gritter-notice-wrapper.bottom-right { + top: auto; + left: auto; + bottom: 20px; + right: 20px; +} +.gritter-item-wrapper { + position:relative; + margin:0 0 10px 0; +} + +.gritter-top { + background:url(../../static/img/gritter.png) no-repeat left -30px; + height:10px; +} +.hover .gritter-top { + background-position:right -30px; +} +.gritter-bottom { + background:url(../../static/img/gritter.png) no-repeat left bottom; + height:8px; + margin:0; +} +.hover .gritter-bottom { + background-position: bottom right; +} +.gritter-item { + display:block; + background:url(../../static/img/gritter.png) no-repeat left -40px; + color:#eee; + padding:2px 11px 8px 11px; + font-size: 11px; + font-family:verdana; +} +.hover .gritter-item { + background-position:right -40px; +} +.gritter-item p { + padding:0; + margin:0; +} +.gritter-close { + display:none; + position:absolute; + top:5px; + left:3px; + background:url('../../static/img/gritter.png') no-repeat left top; + cursor:pointer; + width:30px; + height:30px; +} +.gritter-title { + font-size:14px; + font-weight:bold; + padding:0 0 7px 0; + display:block; + text-shadow:1px 1px 0 #000; /* Not supported by IE :( */ +} +.gritter-image { + width:48px; + height:48px; + float:left; +} +.gritter-with-image, +.gritter-without-image { + padding:0 0 5px 0; +} +.gritter-with-image { + width:220px; + float:right; +} +/* for the light (white) version of the gritter notice */ +.gritter-light .gritter-item, +.gritter-light .gritter-bottom, +.gritter-light .gritter-top, +.gritter-close { + color: #222; +} +.gritter-light .gritter-title { + text-shadow: none; +} + +/* End of gritter stuff */ diff --git a/src/static/img/gritter.png b/src/static/img/gritter.png new file mode 100644 index 00000000..0ca3bc0a Binary files /dev/null and b/src/static/img/gritter.png differ diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index cfea4362..b1604212 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -2182,3 +2182,121 @@ exports.followAttributes = function (att1, att2, pool) { } return buf.toString(); }; + +exports.composeWithDeletions = function (cs1, cs2, pool) { + var unpacked1 = exports.unpack(cs1); + var unpacked2 = exports.unpack(cs2); + var len1 = unpacked1.oldLen; + var len2 = unpacked1.newLen; + exports.assert(len2 == unpacked2.oldLen, "mismatched composition"); + var len3 = unpacked2.newLen; + var bankIter1 = exports.stringIterator(unpacked1.charBank); + var bankIter2 = exports.stringIterator(unpacked2.charBank); + var bankAssem = exports.stringAssembler(); + + var newOps = exports.applyZip(unpacked1.ops, 0, unpacked2.ops, 0, function (op1, op2, opOut) { + var op1code = op1.opcode; + var op2code = op2.opcode; + if (op1code == '+' && op2code == '-') { + bankIter1.skip(Math.min(op1.chars, op2.chars)); + } + exports._slicerZipperFuncWithDeletions(op1, op2, opOut, pool); + if (opOut.opcode == '+') { + if (op2code == '+') { + bankAssem.append(bankIter2.take(opOut.chars)); + } else { + bankAssem.append(bankIter1.take(opOut.chars)); + } + } + }); + + return exports.pack(len1, len3, newOps, bankAssem.toString()); +}; + +// This function is 95% like _slicerZipperFunc, we just changed two lines to ensure it merges the attribs of deletions properly. +// This is necassary for correct paddiff. But to ensure these changes doesn't affect anything else, we've created a seperate function only used for paddiffs +exports._slicerZipperFuncWithDeletions= function (attOp, csOp, opOut, pool) { + // attOp is the op from the sequence that is being operated on, either an + // attribution string or the earlier of two exportss being composed. + // pool can be null if definitely not needed. + //print(csOp.toSource()+" "+attOp.toSource()+" "+opOut.toSource()); + if (attOp.opcode == '-') { + exports.copyOp(attOp, opOut); + attOp.opcode = ''; + } else if (!attOp.opcode) { + exports.copyOp(csOp, opOut); + csOp.opcode = ''; + } else { + switch (csOp.opcode) { + case '-': + { + if (csOp.chars <= attOp.chars) { + // delete or delete part + if (attOp.opcode == '=') { + opOut.opcode = '-'; + opOut.chars = csOp.chars; + opOut.lines = csOp.lines; + opOut.attribs = csOp.attribs; //changed by yammer + } + attOp.chars -= csOp.chars; + attOp.lines -= csOp.lines; + csOp.opcode = ''; + if (!attOp.chars) { + attOp.opcode = ''; + } + } else { + // delete and keep going + if (attOp.opcode == '=') { + opOut.opcode = '-'; + opOut.chars = attOp.chars; + opOut.lines = attOp.lines; + opOut.attribs = csOp.attribs; //changed by yammer + } + csOp.chars -= attOp.chars; + csOp.lines -= attOp.lines; + attOp.opcode = ''; + } + break; + } + case '+': + { + // insert + exports.copyOp(csOp, opOut); + csOp.opcode = ''; + break; + } + case '=': + { + if (csOp.chars <= attOp.chars) { + // keep or keep part + opOut.opcode = attOp.opcode; + opOut.chars = csOp.chars; + opOut.lines = csOp.lines; + opOut.attribs = exports.composeAttributes(attOp.attribs, csOp.attribs, attOp.opcode == '=', pool); + csOp.opcode = ''; + attOp.chars -= csOp.chars; + attOp.lines -= csOp.lines; + if (!attOp.chars) { + attOp.opcode = ''; + } + } else { + // keep and keep going + opOut.opcode = attOp.opcode; + opOut.chars = attOp.chars; + opOut.lines = attOp.lines; + opOut.attribs = exports.composeAttributes(attOp.attribs, csOp.attribs, attOp.opcode == '=', pool); + attOp.opcode = ''; + csOp.chars -= attOp.chars; + csOp.lines -= attOp.lines; + } + break; + } + case '': + { + exports.copyOp(attOp, opOut); + attOp.opcode = ''; + break; + } + } + } +}; diff --git a/src/static/js/admin/plugins.js b/src/static/js/admin/plugins.js index ddff767b..a973875c 100644 --- a/src/static/js/admin/plugins.js +++ b/src/static/js/admin/plugins.js @@ -22,13 +22,10 @@ $(document).ready(function () { var search = function () { socket.emit("search", $('.search-results').data('query')); + tasks++; } function updateHandlers() { - $("#progress.dialog .close").unbind('click').click(function () { - $("#progress.dialog").hide(); - }); - $("form").submit(function(){ var query = $('.search-results').data('query'); query.pattern = $("#search-query").val(); @@ -36,24 +33,26 @@ $(document).ready(function () { search(); return false; }); - - $("#do-search").unbind('click').click(function () { + + $("#search-query").unbind('keyup').keyup(function () { var query = $('.search-results').data('query'); query.pattern = $("#search-query").val(); query.offset = 0; search(); }); - $(".do-install").unbind('click').click(function (e) { + $(".do-install, .do-update").unbind('click').click(function (e) { var row = $(e.target).closest("tr"); doUpdate = true; - socket.emit("install", row.find(".name").html()); + socket.emit("install", row.find(".name").text()); + tasks++; }); $(".do-uninstall").unbind('click').click(function (e) { var row = $(e.target).closest("tr"); doUpdate = true; - socket.emit("uninstall", row.find(".name").html()); + socket.emit("uninstall", row.find(".name").text()); + tasks++; }); $(".do-prev-page").unbind('click').click(function (e) { @@ -76,33 +75,37 @@ $(document).ready(function () { updateHandlers(); + var tasks = 0; socket.on('progress', function (data) { - if (data.progress > 0 && $('#progress.dialog').data('progress') > data.progress) return; - - $("#progress.dialog .close").hide(); - $("#progress.dialog").show(); - - $('#progress.dialog').data('progress', data.progress); + $("#progress").show(); + $('#progress').data('progress', data.progress); var message = "Unknown status"; if (data.message) { - message = "" + data.message.toString() + ""; + message = data.message.toString(); } if (data.error) { - message = "" + data.error.toString() + ""; + data.progress = 1; } - $("#progress.dialog .message").html(message); - $("#progress.dialog .history").append("
" + message + "
"); + + $("#progress .message").html(message); if (data.progress >= 1) { + tasks--; + if (tasks <= 0) { + // Hide the activity indicator once all tasks are done + $("#progress").hide(); + tasks = 0; + } + if (data.error) { - $("#progress.dialog .close").show(); - } else { + alert('An error occurred: '+data.error+' -- the server log might know more...'); + }else { if (doUpdate) { doUpdate = false; socket.emit("load"); + tasks++; } - $("#progress.dialog").hide(); } } }); @@ -114,21 +117,26 @@ $(document).ready(function () { widget.data('total', data.total); widget.find('.offset').html(data.query.offset); - widget.find('.limit').html(data.query.offset + data.query.limit); + if (data.query.offset + data.query.limit > data.total){ + widget.find('.limit').html(data.total); + }else{ + widget.find('.limit').html(data.query.offset + data.query.limit); + } widget.find('.total').html(data.total); widget.find(".results *").remove(); for (plugin_name in data.results) { var plugin = data.results[plugin_name]; var row = widget.find(".template tr").clone(); - var version = '0.0.0'; - // hack to access "versions" property of the npm package object - for (version in data.results[plugin_name].versions) break; - + for (attr in plugin) { - row.find("." + attr).html(plugin[attr]); + if(attr == "name"){ // Hack to rewrite URLS into name + row.find(".name").html(""+plugin[attr]+""); + }else{ + row.find("." + attr).html(plugin[attr]); + } } - row.find(".version").html(version); + row.find(".version").html( data.results[plugin_name]['dist-tags'].latest ); widget.find(".results").append(row); } @@ -138,20 +146,42 @@ $(document).ready(function () { socket.on('installed-results', function (data) { $("#installed-plugins *").remove(); + for (plugin_name in data.results) { if (plugin_name == "ep_etherpad-lite") continue; // Hack... var plugin = data.results[plugin_name]; var row = $("#installed-plugin-template").clone(); for (attr in plugin.package) { - row.find("." + attr).html(plugin.package[attr]); + if(attr == "name"){ // Hack to rewrite URLS into name + row.find(".name").html(""+plugin.package[attr]+""); + }else{ + row.find("." + attr).html(plugin.package[attr]); + } } $("#installed-plugins").append(row); } updateHandlers(); + + socket.emit('checkUpdates'); + tasks++; }); + + socket.on('updatable', function(data) { + $('#installed-plugins>tr').each(function(i,tr) { + var pluginName = $(tr).find('.name').text() + + if (data.updatable.indexOf(pluginName) >= 0) { + var actions = $(tr).find('.actions') + actions.append('') + actions.css('width', 200) + } + }) + updateHandlers(); + }) socket.emit("load"); + tasks++; + search(); - }); diff --git a/src/static/js/broadcast_slider.js b/src/static/js/broadcast_slider.js index d4fbef81..08ac08b5 100644 --- a/src/static/js/broadcast_slider.js +++ b/src/static/js/broadcast_slider.js @@ -107,6 +107,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded) { newpos = Number(newpos); if (newpos < 0 || newpos > sliderLength) return; + window.location.hash = "#" + newpos; $("#ui-slider-handle").css('left', newpos * ($("#ui-slider-bar").width() - 2) / (sliderLength * 1.0)); $("a.tlink").map(function() { @@ -193,7 +194,12 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded) }); if (numAnonymous > 0) { - var anonymousAuthorString = numAnonymous + " unnamed author" + (numAnonymous > 1 ? "s" : "") + var anonymousAuthorString; + if(numAnonymous == 1) + anonymousAuthorString = html10n.get("timeslider.unnamedauthor", { num: numAnonymous }); + else + anonymousAuthorString = html10n.get("timeslider.unnamedauthors", { num: numAnonymous }); + if (numNamed !== 0){ authorsList.append(' + ' + anonymousAuthorString); } else { @@ -361,7 +367,11 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded) $(self).css('left', newloc); // if(getSliderPosition() != Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width()-2))) setSliderPosition(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))) - self.currentLoc = parseInt($(self).css('left')); + if(parseInt($(self).css('left')) < 2){ + $(self).css('left', '2px'); + }else{ + self.currentLoc = parseInt($(self).css('left')); + } }); }) @@ -472,6 +482,18 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded) } $("#timeslider").show(); + + var startPos = clientVars.collab_client_vars.rev; + if(window.location.hash.length > 1) + { + var hashRev = Number(window.location.hash.substr(1)); + if(!isNaN(hashRev)) + { + // this is necessary because of the socket.io-event which loads the changesets + setTimeout(function() { setSliderPosition(hashRev); }, 1); + } + } + setSliderLength(clientVars.collab_client_vars.rev); setSliderPosition(clientVars.collab_client_vars.rev); diff --git a/src/static/js/chat.js b/src/static/js/chat.js index 205294a8..2dff2edf 100644 --- a/src/static/js/chat.js +++ b/src/static/js/chat.js @@ -1,9 +1,3 @@ -/** - * This code is mostly from the old Etherpad. Please help us to comment this code. - * This helps other people to understand this code better and helps them to improve it. - * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED - */ - /** * Copyright 2009 Google Inc., 2011 Peter 'Pita' Martischka (Primary Technology Ltd) * @@ -22,7 +16,6 @@ var padutils = require('./pad_utils').padutils; var padcookie = require('./pad_cookie').padcookie; - var Tinycon = require('tinycon/tinycon'); var chat = (function() @@ -36,6 +29,7 @@ var chat = (function() { $("#chaticon").hide(); $("#chatbox").show(); + $("#gritter-notice-wrapper").hide(); self.scrollDown(); chatMentions = 0; Tinycon.setBubble(0); @@ -62,6 +56,8 @@ var chat = (function() $("#chatcounter").text("0"); $("#chaticon").show(); $("#chatbox").hide(); + $.gritter.removeAll(); + $("#gritter-notice-wrapper").show(); }, scrollDown: function() { @@ -122,7 +118,7 @@ var chat = (function() $("#chattext").append(html); //should we increment the counter?? - if(increment) + if(increment && !isHistoryAdd) { var count = Number($("#chatcounter").text()); count++; @@ -130,17 +126,44 @@ var chat = (function() // is the users focus already in the chatbox? var alreadyFocused = $("#chatinput").is(":focus"); + // does the user already have the chatbox open? + var chatOpen = $("#chatbox").is(":visible"); + $("#chatcounter").text(count); // chat throb stuff -- Just make it throw for twice as long - if(wasMentioned && !alreadyFocused && !isHistoryAdd) + if(wasMentioned && !alreadyFocused && !isHistoryAdd && !chatOpen) { // If the user was mentioned show for twice as long and flash the browser window - $('#chatthrob').html(""+authorName+"" + ": " + text).show().delay(4000).hide(400); + $.gritter.add({ + // (string | mandatory) the heading of the notification + title: authorName, + // (string | mandatory) the text inside the notification + text: text, + // (bool | optional) if you want it to fade out on its own or just sit there + sticky: true, + // (int | optional) the time you want it to be alive for before fading out + time: '2000' + }); + chatMentions++; Tinycon.setBubble(chatMentions); } else { - $('#chatthrob').html(""+authorName+"" + ": " + text).show().delay(2000).hide(400); + if(!chatOpen){ + $.gritter.add({ + // (string | mandatory) the heading of the notification + title: authorName, + // (string | mandatory) the text inside the notification + text: text, + + // (bool | optional) if you want it to fade out on its own or just sit there + sticky: false, + // (int | optional) the time you want it to be alive for before fading out + time: '4000' + }); + Tinycon.setBubble(count); + + } } } // Clear the chat mentions when the user clicks on the chat input box diff --git a/src/static/js/gritter.js b/src/static/js/gritter.js new file mode 100644 index 00000000..c32cc758 --- /dev/null +++ b/src/static/js/gritter.js @@ -0,0 +1,417 @@ +/* + * Gritter for jQuery + * http://www.boedesign.com/ + * + * Copyright (c) 2012 Jordan Boesch + * Dual licensed under the MIT and GPL licenses. + * + * Date: February 24, 2012 + * Version: 1.7.4 + */ + +(function($){ + /** + * Set it up as an object under the jQuery namespace + */ + $.gritter = {}; + + /** + * Set up global options that the user can over-ride + */ + $.gritter.options = { + position: '', + class_name: '', // could be set to 'gritter-light' to use white notifications + fade_in_speed: 'medium', // how fast notifications fade in + fade_out_speed: 1000, // how fast the notices fade out + time: 6000 // hang on the screen for... + } + + /** + * Add a gritter notification to the screen + * @see Gritter#add(); + */ + $.gritter.add = function(params){ + + try { + return Gritter.add(params || {}); + } catch(e) { + + var err = 'Gritter Error: ' + e; + (typeof(console) != 'undefined' && console.error) ? + console.error(err, params) : + alert(err); + + } + + } + + /** + * Remove a gritter notification from the screen + * @see Gritter#removeSpecific(); + */ + $.gritter.remove = function(id, params){ + Gritter.removeSpecific(id, params || {}); + } + + /** + * Remove all notifications + * @see Gritter#stop(); + */ + $.gritter.removeAll = function(params){ + Gritter.stop(params || {}); + } + + /** + * Big fat Gritter object + * @constructor (not really since its object literal) + */ + var Gritter = { + + // Public - options to over-ride with $.gritter.options in "add" + position: '', + fade_in_speed: '', + fade_out_speed: '', + time: '', + + // Private - no touchy the private parts + _custom_timer: 0, + _item_count: 0, + _is_setup: 0, + _tpl_close: '
', + _tpl_title: '[[title]]', + _tpl_item: '', + _tpl_wrap: '
', + + /** + * Add a gritter notification to the screen + * @param {Object} params The object that contains all the options for drawing the notification + * @return {Integer} The specific numeric id to that gritter notification + */ + add: function(params){ + // Handle straight text + if(typeof(params) == 'string'){ + params = {text:params}; + } + + // We might have some issues if we don't have a title or text! + if(!params.text){ + throw 'You must supply "text" parameter.'; + } + + // Check the options and set them once + if(!this._is_setup){ + this._runSetup(); + } + + // Basics + var title = params.title, + text = params.text, + image = params.image || '', + sticky = params.sticky || false, + item_class = params.class_name || $.gritter.options.class_name, + position = $.gritter.options.position, + time_alive = params.time || ''; + + this._verifyWrapper(); + + this._item_count++; + var number = this._item_count, + tmp = this._tpl_item; + + // Assign callbacks + $(['before_open', 'after_open', 'before_close', 'after_close']).each(function(i, val){ + Gritter['_' + val + '_' + number] = ($.isFunction(params[val])) ? params[val] : function(){} + }); + + // Reset + this._custom_timer = 0; + + // A custom fade time set + if(time_alive){ + this._custom_timer = time_alive; + } + + var image_str = (image != '') ? '' : '', + class_name = (image != '') ? 'gritter-with-image' : 'gritter-without-image'; + + // String replacements on the template + if(title){ + title = this._str_replace('[[title]]',title,this._tpl_title); + }else{ + title = ''; + } + + tmp = this._str_replace( + ['[[title]]', '[[text]]', '[[close]]', '[[image]]', '[[number]]', '[[class_name]]', '[[item_class]]'], + [title, text, this._tpl_close, image_str, this._item_count, class_name, item_class], tmp + ); + + // If it's false, don't show another gritter message + if(this['_before_open_' + number]() === false){ + return false; + } + + $('#gritter-notice-wrapper').addClass(position).append(tmp); + + var item = $('#gritter-item-' + this._item_count); + + item.fadeIn(this.fade_in_speed, function(){ + Gritter['_after_open_' + number]($(this)); + }); + + if(!sticky){ + this._setFadeTimer(item, number); + } + + // Bind the hover/unhover states + $(item).bind('mouseenter mouseleave', function(event){ + if(event.type == 'mouseenter'){ + if(!sticky){ + Gritter._restoreItemIfFading($(this), number); + } + } + else { + if(!sticky){ + Gritter._setFadeTimer($(this), number); + } + } + Gritter._hoverState($(this), event.type); + }); + + // Clicking (X) makes the perdy thing close + $(item).find('.gritter-close').click(function(){ + Gritter.removeSpecific(number, {}, null, true); + }); + + return number; + + }, + + /** + * If we don't have any more gritter notifications, get rid of the wrapper using this check + * @private + * @param {Integer} unique_id The ID of the element that was just deleted, use it for a callback + * @param {Object} e The jQuery element that we're going to perform the remove() action on + * @param {Boolean} manual_close Did we close the gritter dialog with the (X) button + */ + _countRemoveWrapper: function(unique_id, e, manual_close){ + + // Remove it then run the callback function + e.remove(); + this['_after_close_' + unique_id](e, manual_close); + + // Check if the wrapper is empty, if it is.. remove the wrapper + if($('.gritter-item-wrapper').length == 0){ + $('#gritter-notice-wrapper').remove(); + } + + }, + + /** + * Fade out an element after it's been on the screen for x amount of time + * @private + * @param {Object} e The jQuery element to get rid of + * @param {Integer} unique_id The id of the element to remove + * @param {Object} params An optional list of params to set fade speeds etc. + * @param {Boolean} unbind_events Unbind the mouseenter/mouseleave events if they click (X) + */ + _fade: function(e, unique_id, params, unbind_events){ + + var params = params || {}, + fade = (typeof(params.fade) != 'undefined') ? params.fade : true, + fade_out_speed = params.speed || this.fade_out_speed, + manual_close = unbind_events; + + this['_before_close_' + unique_id](e, manual_close); + + // If this is true, then we are coming from clicking the (X) + if(unbind_events){ + e.unbind('mouseenter mouseleave'); + } + + // Fade it out or remove it + if(fade){ + + e.animate({ + opacity: 0 + }, fade_out_speed, function(){ + e.animate({ height: 0 }, 300, function(){ + Gritter._countRemoveWrapper(unique_id, e, manual_close); + }) + }) + + } + else { + + this._countRemoveWrapper(unique_id, e); + + } + + }, + + /** + * Perform actions based on the type of bind (mouseenter, mouseleave) + * @private + * @param {Object} e The jQuery element + * @param {String} type The type of action we're performing: mouseenter or mouseleave + */ + _hoverState: function(e, type){ + + // Change the border styles and add the (X) close button when you hover + if(type == 'mouseenter'){ + + e.addClass('hover'); + + // Show close button + e.find('.gritter-close').show(); + + } + // Remove the border styles and hide (X) close button when you mouse out + else { + + e.removeClass('hover'); + + // Hide close button + e.find('.gritter-close').hide(); + + } + + }, + + /** + * Remove a specific notification based on an ID + * @param {Integer} unique_id The ID used to delete a specific notification + * @param {Object} params A set of options passed in to determine how to get rid of it + * @param {Object} e The jQuery element that we're "fading" then removing + * @param {Boolean} unbind_events If we clicked on the (X) we set this to true to unbind mouseenter/mouseleave + */ + removeSpecific: function(unique_id, params, e, unbind_events){ + + if(!e){ + var e = $('#gritter-item-' + unique_id); + } + + // We set the fourth param to let the _fade function know to + // unbind the "mouseleave" event. Once you click (X) there's no going back! + this._fade(e, unique_id, params || {}, unbind_events); + + }, + + /** + * If the item is fading out and we hover over it, restore it! + * @private + * @param {Object} e The HTML element to remove + * @param {Integer} unique_id The ID of the element + */ + _restoreItemIfFading: function(e, unique_id){ + + clearTimeout(this['_int_id_' + unique_id]); + e.stop().css({ opacity: '', height: '' }); + + }, + + /** + * Setup the global options - only once + * @private + */ + _runSetup: function(){ + + for(opt in $.gritter.options){ + this[opt] = $.gritter.options[opt]; + } + this._is_setup = 1; + + }, + + /** + * Set the notification to fade out after a certain amount of time + * @private + * @param {Object} item The HTML element we're dealing with + * @param {Integer} unique_id The ID of the element + */ + _setFadeTimer: function(e, unique_id){ + + var timer_str = (this._custom_timer) ? this._custom_timer : this.time; + this['_int_id_' + unique_id] = setTimeout(function(){ + Gritter._fade(e, unique_id); + }, timer_str); + + }, + + /** + * Bring everything to a halt + * @param {Object} params A list of callback functions to pass when all notifications are removed + */ + stop: function(params){ + + // callbacks (if passed) + var before_close = ($.isFunction(params.before_close)) ? params.before_close : function(){}; + var after_close = ($.isFunction(params.after_close)) ? params.after_close : function(){}; + + var wrap = $('#gritter-notice-wrapper'); + before_close(wrap); + wrap.fadeOut(function(){ + $(this).remove(); + after_close(); + }); + + }, + + /** + * An extremely handy PHP function ported to JS, works well for templating + * @private + * @param {String/Array} search A list of things to search for + * @param {String/Array} replace A list of things to replace the searches with + * @return {String} sa The output + */ + _str_replace: function(search, replace, subject, count){ + + var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0, + f = [].concat(search), + r = [].concat(replace), + s = subject, + ra = r instanceof Array, sa = s instanceof Array; + s = [].concat(s); + + if(count){ + this.window[count] = 0; + } + + for(i = 0, sl = s.length; i < sl; i++){ + + if(s[i] === ''){ + continue; + } + + for (j = 0, fl = f.length; j < fl; j++){ + + temp = s[i] + ''; + repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0]; + s[i] = (temp).split(f[j]).join(repl); + + if(count && s[i] !== temp){ + this.window[count] += (temp.length-s[i].length) / f[j].length; + } + + } + } + + return sa ? s : s[0]; + + }, + + /** + * A check to make sure we have something to wrap our notices with + * @private + */ + _verifyWrapper: function(){ + + if($('#gritter-notice-wrapper').length == 0){ + $('body').append(this._tpl_wrap); + } + + } + + } + +})(jQuery); diff --git a/src/static/js/html10n.js b/src/static/js/html10n.js index b2c4e619..d0d14814 100644 --- a/src/static/js/html10n.js +++ b/src/static/js/html10n.js @@ -21,6 +21,8 @@ * IN THE SOFTWARE. */ window.html10n = (function(window, document, undefined) { + + // fix console var console = window.console function interceptConsole(method){ if (!console) return function() {} @@ -44,6 +46,39 @@ window.html10n = (function(window, document, undefined) { , consoleError = interceptConsole('warn') + // fix Array.prototype.instanceOf in, guess what, IE! <3 + if (!Array.prototype.indexOf) { + Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) { + "use strict"; + if (this == null) { + throw new TypeError(); + } + var t = Object(this); + var len = t.length >>> 0; + if (len === 0) { + return -1; + } + var n = 0; + if (arguments.length > 1) { + n = Number(arguments[1]); + if (n != n) { // shortcut for verifying if it's NaN + n = 0; + } else if (n != 0 && n != Infinity && n != -Infinity) { + n = (n > 0 || -1) * Math.floor(Math.abs(n)); + } + } + if (n >= len) { + return -1; + } + var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); + for (; k < len; k++) { + if (k in t && t[k] === searchElement) { + return k; + } + } + return -1; + } + } /** * MicroEvent - to make any js object an event emitter (server or browser) diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 64d8b42b..27dd3b73 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -48,6 +48,7 @@ var colorutils = require('./colorutils').colorutils; var createCookie = require('./pad_utils').createCookie; var readCookie = require('./pad_utils').readCookie; var randomString = require('./pad_utils').randomString; +var gritter = require('./gritter').gritter; var hooks = require('./pluginfw/hooks'); @@ -101,86 +102,39 @@ function randomString() return "t." + randomstring; } +// This array represents all GET-parameters which can be used to change a setting. +// name: the parameter-name, eg `?noColors=true` => `noColors` +// checkVal: the callback is only executed when +// * the parameter was supplied and matches checkVal +// * the parameter was supplied and checkVal is null +// callback: the function to call when all above succeeds, `val` is the value supplied by the user +var getParameters = [ + { name: "noColors", checkVal: "true", callback: function(val) { settings.noColors = true; $('#clearAuthorship').hide(); } }, + { name: "showControls", checkVal: "false", callback: function(val) { $('#editbar').hide(); $('#editorcontainer').css({"top":"0px"}); } }, + { name: "showChat", checkVal: "false", callback: function(val) { $('#chaticon').hide(); } }, + { name: "showLineNumbers", checkVal: "false", callback: function(val) { settings.LineNumbersDisabled = true; } }, + { name: "useMonospaceFont", checkVal: "true", callback: function(val) { settings.useMonospaceFontGlobal = true; } }, + // If the username is set as a parameter we should set a global value that we can call once we have initiated the pad. + { name: "userName", checkVal: null, callback: function(val) { settings.globalUserName = decodeURIComponent(val); } }, + // If the userColor is set as a parameter, set a global value to use once we have initiated the pad. + { name: "userColor", checkVal: null, callback: function(val) { settings.globalUserColor = decodeURIComponent(val); } }, + { name: "rtl", checkVal: "true", callback: function(val) { settings.rtlIsTrue = true } }, + { name: "alwaysShowChat", checkVal: "true", callback: function(val) { chat.stickToScreen(); } }, + { name: "lang", checkVal: null, callback: function(val) { window.html10n.localize([val, 'en']); } } +]; + function getParams() { var params = getUrlVars() - var showControls = params["showControls"]; - var showChat = params["showChat"]; - var userName = params["userName"]; - var userColor = params["userColor"]; - var showLineNumbers = params["showLineNumbers"]; - var useMonospaceFont = params["useMonospaceFont"]; - var IsnoColors = params["noColors"]; - var rtl = params["rtl"]; - var alwaysShowChat = params["alwaysShowChat"]; - var lang = params["lang"]; - - if(IsnoColors) + + for(var i = 0; i < getParameters.length; i++) { - if(IsnoColors == "true") + var setting = getParameters[i]; + var value = params[setting.name]; + + if(value && (value == setting.checkVal || setting.checkVal == null)) { - settings.noColors = true; - $('#clearAuthorship').hide(); - } - } - if(showControls) - { - if(showControls == "false") - { - $('#editbar').hide(); - $('#editorcontainer').css({"top":"0px"}); - } - } - if(showChat) - { - if(showChat == "false") - { - $('#chaticon').hide(); - } - } - if(showLineNumbers) - { - if(showLineNumbers == "false") - { - settings.LineNumbersDisabled = true; - } - } - if(useMonospaceFont) - { - if(useMonospaceFont == "true") - { - settings.useMonospaceFontGlobal = true; - } - } - if(userName) - { - // If the username is set as a parameter we should set a global value that we can call once we have initiated the pad. - settings.globalUserName = decodeURIComponent(userName); - } - if(userColor) - // If the userColor is set as a parameter, set a global value to use once we have initiated the pad. - { - settings.globalUserColor = decodeURIComponent(userColor); - } - if(rtl) - { - if(rtl == "true") - { - settings.rtlIsTrue = true - } - } - if(alwaysShowChat) - { - if(alwaysShowChat == "true") - { - chat.stickToScreen(); - } - } - if(lang) - { - if(lang !== "") - { - window.html10n.localize([lang, 'en']); + setting.callback(value); } } } @@ -410,6 +364,13 @@ function handshake() }); } +$.extend($.gritter.options, { + position: 'bottom-right', // defaults to 'top-right' but can be 'bottom-left', 'bottom-right', 'top-left', 'top-right' (added in 1.7.1) + fade_in_speed: 'medium', // how fast notifications fade in (string or int) + fade_out_speed: 2000, // how fast the notices fade out + time: 6000 // hang on the screen for... +}); + var pad = { // don't access these directly from outside this file, except // for debugging diff --git a/src/static/js/pad_editor.js b/src/static/js/pad_editor.js index f4778802..dd0cbbbb 100644 --- a/src/static/js/pad_editor.js +++ b/src/static/js/pad_editor.js @@ -78,6 +78,16 @@ var padeditor = (function() html10n.bind('localized', function() { $("#languagemenu").val(html10n.getLanguage()); + // translate the value of 'unnamed' and 'Enter your name' textboxes in the userlist + // this does not interfere with html10n's normal value-setting because html10n just ingores s + // also, a value which has been set by the user will be not overwritten since a user-edited + // does *not* have the editempty-class + $('input[data-l10n-id]').each(function(key, input) + { + input = $(input); + if(input.hasClass("editempty")) + input.val(html10n.get(input.attr("data-l10n-id"))); + }); }) $("#languagemenu").val(html10n.getLanguage()); $("#languagemenu").change(function() { diff --git a/src/static/js/pad_impexp.js b/src/static/js/pad_impexp.js index c7a26fbe..74564256 100644 --- a/src/static/js/pad_impexp.js +++ b/src/static/js/pad_impexp.js @@ -211,9 +211,9 @@ var padimpexp = (function() pad = _pad; //get /p/padname - var pad_root_path = new RegExp(/.*\/p\/[^\/]+/).exec(document.location.pathname) - //get http://example.com/p/padname - var pad_root_url = document.location.href.replace(document.location.pathname, pad_root_path) + var pad_root_path = new RegExp(/.*\/p\/[^\/]+/).exec(document.location.pathname); + //get http://example.com/p/padname without Params + var pad_root_url = document.location.protocol + '//' + document.location.host + document.location.pathname; //i10l buttom import $('#importsubmitinput').val(html10n.get("pad.impexp.importbutton")); diff --git a/src/static/js/pad_userlist.js b/src/static/js/pad_userlist.js index 40e87a4f..d051182b 100644 --- a/src/static/js/pad_userlist.js +++ b/src/static/js/pad_userlist.js @@ -118,7 +118,7 @@ var paduserlist = (function() } else { - nameHtml = ''; + nameHtml = ''; } return ['
 
', '', nameHtml, '', '', padutils.escapeHtml(data.activity), ''].join(''); @@ -710,8 +710,7 @@ var paduserlist = (function() { if (myUserInfo.name) { - $("#myusernameedit").removeClass("editempty").val( - myUserInfo.name); + $("#myusernameedit").removeClass("editempty").val(myUserInfo.name); } else { diff --git a/src/static/js/pluginfw/installer.js b/src/static/js/pluginfw/installer.js index e491f077..eb10f8af 100644 --- a/src/static/js/pluginfw/installer.js +++ b/src/static/js/pluginfw/installer.js @@ -15,7 +15,10 @@ var withNpm = function (npmfn, final, cb) { cb({progress: 0.5, message:message.msg + ": " + message.pref}); }); npmfn(function (er, data) { - if (er) return cb({progress:1, error:er.code + ": " + er.path}); + if (er) { + console.error(er); + return cb({progress:1, error: er.message}); + } if (!data) data = {}; data.progress = 1; data.message = "Done."; diff --git a/src/templates/admin/index.html b/src/templates/admin/index.html index 5f1d0188..16ea8427 100644 --- a/src/templates/admin/index.html +++ b/src/templates/admin/index.html @@ -1,6 +1,6 @@ - Etherpad Lite Admin Dashboard + Admin Dashboard - Etherpad lite @@ -8,13 +8,14 @@
-

Etherpad Lite Admin Dashboard

-
- Install and Uninstall plugins -
-
- Modify Server and Plugin Settings + +
+
diff --git a/src/templates/admin/plugins-info.html b/src/templates/admin/plugins-info.html index 94f94e2a..605b23d3 100644 --- a/src/templates/admin/plugins-info.html +++ b/src/templates/admin/plugins-info.html @@ -4,27 +4,36 @@ - Plugin information + Plugin information - Etherpad lite
-

Etherpad Lite

-
+ -

Installed plugins

-
<%- plugins.formatPlugins().replace(", ","\n") %>
+
-

Installed parts

-
<%= plugins.formatParts() %>
+

Installed plugins

+
<%- plugins.formatPlugins().replace(", ","\n") %>
-

Installed hooks

-

Server side hooks

-
<%- plugins.formatHooks() %>
+

Installed parts

+
<%= plugins.formatParts() %>
-

Client side hooks

-
<%- plugins.formatHooks("client_hooks") %>
+

Installed hooks

+

Server side hooks

+
<%- plugins.formatHooks() %>
+ +

Client side hooks

+
<%- plugins.formatHooks("client_hooks") %>
+ +
+
diff --git a/src/templates/admin/plugins.html b/src/templates/admin/plugins.html index 394cf0e0..a85db557 100644 --- a/src/templates/admin/plugins.html +++ b/src/templates/admin/plugins.html @@ -1,6 +1,6 @@ - Plugin manager + Plugin manager - Etherpad lite @@ -18,12 +18,16 @@
<% } %> + -

Etherpad Lite

- - Technical information on installed plugins - -
+

Installed plugins

@@ -50,11 +54,12 @@
-

Search for plugins to install

+ +

Available plugins

- - + +
@@ -81,14 +86,9 @@ .. of . - -
-

- Please wait: - -

-
+
+
diff --git a/src/templates/admin/settings.html b/src/templates/admin/settings.html index c4f50578..be262f24 100644 --- a/src/templates/admin/settings.html +++ b/src/templates/admin/settings.html @@ -1,6 +1,6 @@ - Settings manager + Settings - Etherpad lite @@ -22,13 +22,23 @@ <% } %> -

Etherpad Lite Settings

- Example production settings template - Example development settings template - - - -
+ + + + +
diff --git a/src/templates/index.html b/src/templates/index.html index f0e1beb3..c3c13db3 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -150,6 +150,7 @@
+ <% e.begin_block("indexWrapper"); %>
@@ -158,6 +159,7 @@
+ <% e.end_block(); %>
diff --git a/src/templates/pad.html b/src/templates/pad.html index 274a3b1a..76df5133 100644 --- a/src/templates/pad.html +++ b/src/templates/pad.html @@ -3,7 +3,10 @@ , langs = require("ep_etherpad-lite/node/hooks/i18n").availableLangs %> +<% e.begin_block("htmlHead"); %> +<% e.end_block(); %> + <%=settings.title%>